#!/usr/bin/env python3
#
# Copyright (c) 2020 Intel Corporation.
#
# SPDX-License-Identifier: Apache-2.0
"""
Script to parse CTF data and print to the screen in a custom and colorful
format.

Generate trace using samples/subsys/tracing for example:

    west build -b qemu_x86 samples/subsys/tracing  -t run \
      -- -DCONF_FILE=prj_uart_ctf.conf

    mkdir ctf
    cp build/channel0_0 ctf/
    cp subsys/tracing/ctf/tsdl/metadata ctf/
    ./scripts/tracing/parse_ctf.py -t ctf
"""

import sys
import datetime
import colorama
from colorama import Fore
import argparse
try:
    import bt2
except ImportError:
    sys.exit("Missing dependency: You need to install python bindings of babeltrace.")

def parse_args():
    parser = argparse.ArgumentParser(
            description=__doc__,
            formatter_class=argparse.RawDescriptionHelpFormatter, allow_abbrev=False)
    parser.add_argument("-t", "--trace",
            required=True,
            help="tracing data (directory with metadata and trace file)")
    args = parser.parse_args()
    return args

def main():
    colorama.init()

    args = parse_args()

    msg_it = bt2.TraceCollectionMessageIterator(args.trace)
    last_event_ns_from_origin = None
    timeline = []

    def get_thread(name):
        for t in timeline:
            if t.get('name', None) == name and t.get('in', 0 ) != 0 and not t.get('out', None):
                return t
        return {}

    for msg in msg_it:

        if not isinstance(msg, bt2._EventMessageConst):
            continue

        ns_from_origin = msg.default_clock_snapshot.ns_from_origin
        event = msg.event
        # Compute the time difference since the last event message.
        diff_s = 0

        if last_event_ns_from_origin is not None:
            diff_s = (ns_from_origin - last_event_ns_from_origin) / 1e9

        dt = datetime.datetime.fromtimestamp(ns_from_origin / 1e9)

        if event.name in [
                'thread_switched_out',
                'thread_switched_in',
                'thread_pending',
                'thread_ready',
                'thread_resume',
                'thread_suspend',
                'thread_create',
                'thread_abort'
                ]:

            cpu = event.payload_field.get("cpu", None)
            thread_id = event.payload_field.get("thread_id", None)
            thread_name = event.payload_field.get("name", None)

            th = {}
            if event.name in ['thread_switched_out', 'thread_switched_in'] and cpu is not None:
                cpu_string = f"(cpu: {cpu})"
            else:
                cpu_string = ""

            if thread_name:
                print(f"{dt} (+{diff_s:.6f} s): {event.name}: {thread_name} {cpu_string}")
            elif thread_id:
                print(f"{dt} (+{diff_s:.6f} s): {event.name}: {thread_id} {cpu_string}")
            else:
                print(f"{dt} (+{diff_s:.6f} s): {event.name}")

            if event.name in ['thread_switched_out', 'thread_switched_in']:
                if thread_name:
                    th = get_thread(thread_name)
                    if not th:
                        th['name'] = thread_name
                else:
                    th = get_thread(thread_id)
                    if not th:
                        th['name'] = thread_id

                if event.name in ['thread_switched_out']:
                    th['out'] = ns_from_origin
                    tin = th.get('in', None)
                    tout = th.get('out', None)
                    if tout is not None and tin is not None:
                        diff = tout - tin
                        th['runtime'] = diff
                elif event.name in ['thread_switched_in']:
                    th['in'] = ns_from_origin

                    timeline.append(th)

        elif event.name in ['thread_info']:
            stack_size = event.payload_field['stack_size']
            print(f"{dt} (+{diff_s:.6f} s): {event.name} (Stack size: {stack_size})")
        elif event.name in ['start_call', 'end_call']:
            if event.payload_field['id'] == 39:
                c = Fore.GREEN
            elif event.payload_field['id'] in [37, 38]:
                c = Fore.CYAN
            else:
                c = Fore.YELLOW
            print(c + f"{dt} (+{diff_s:.6f} s): {event.name} {event.payload_field['id']}" + Fore.RESET)
        elif event.name in ['semaphore_init', 'semaphore_take', 'semaphore_give']:
            c = Fore.CYAN
            print(c + f"{dt} (+{diff_s:.6f} s): {event.name} ({event.payload_field['id']})" + Fore.RESET)
        elif event.name in ['mutex_init', 'mutex_take', 'mutex_give']:
            c = Fore.MAGENTA
            print(c + f"{dt} (+{diff_s:.6f} s): {event.name} ({event.payload_field['id']})" + Fore.RESET)

        elif event.name in ['named_event']:
            name = event.payload_field['name']
            arg0 = event.payload_field['arg0']
            arg1 = event.payload_field['arg1']
            print(f"{dt} (+{diff_s:.6f} s): {event.name} (name: {name}, arg0: {arg0} arg1: {arg1})")
        else:
            print(f"{dt} (+{diff_s:.6f} s): {event.name}")

        last_event_ns_from_origin = ns_from_origin

if __name__=="__main__":
    main()
