import os
import subprocess
import glob
import re
import time
from datetime import datetime
from helpers.ConfigHelper import is_windows


def get_core_dumps():
    # TODO: find a way to use coredump in windows
    if is_windows():
        return False
    # read coredump location
    with open('/proc/sys/kernel/core_pattern', 'r', encoding='utf-8') as f:
        coredump_path = f.read().strip('\n')

    # yields something like: /tmp/core-*-*-*-*
    coredump_file_pattern = re.sub(r'%[a-zA-Z]{1}', '*', coredump_path)
    return glob.glob(coredump_file_pattern)


def generate_stacktrace(scenario_title, coredumps):
    message = ['###########################################']
    message.append(f'Scenario: {scenario_title}')

    for coredump_file in coredumps:
        message.append(parse_stacktrace(coredump_file))

    message.append('###########################################')
    message.append('')
    stacktrace = '\n'.join(message)

    stacktrace_file = os.environ.get('STACKTRACE_FILE', '../stacktrace.log')
    # save stacktrace to a file
    with open(stacktrace_file, 'a', encoding='utf-8') as f:
        f.write(stacktrace)


def parse_stacktrace(coredump_file):
    message = []
    if coredump_file:
        coredump_filename = os.path.basename(coredump_file)
        # example coredump file: core-1648445754-1001-11-!drone!src!build-GUI-tests!bin!qsfera
        patterns = coredump_filename.split('-')
        app_binary = 'qsfera'
        if len(patterns) == 1:
            patterns.append('N/A')
            patterns.append('N/A')
            patterns.append('N/A')
        else:
            app_binary = '-'.join(patterns[4:]).replace('!', '/')

        timestamp = datetime.fromtimestamp(
            float(patterns[1] if patterns[1] != 'N/A' else time.time())
        )
        message.append('-------------------------------------------')
        message.append(f'Executable: {app_binary}')
        message.append(f'Timestamp: {str(timestamp)}')
        message.append(f'Process ID: {patterns[2]}')
        message.append(f'Signal Number: {patterns[3]}')
        message.append('-------------------------------------------')
        message.append('<<<<< STACKTRACE START >>>>>')
        message.append(
            subprocess.run(
                [
                    'gdb',
                    app_binary,
                    coredump_file,
                    '-batch',
                    '-ex',
                    'bt full',
                ],
                stdout=subprocess.PIPE,
                check=False,
            ).stdout.decode('utf-8')
        )
        message.append('<<<<< STACKTRACE END >>>>>')

        # remove coredump file
        os.unlink(coredump_file)

    return '\n'.join(message)
