"""
Test that we can backtrace correctly from standard functions.

This test suit is a collection of automatically generated tests from the source files in the
directory. Please DON'T add individual test cases to this file.

To add a new test case to this test suit please create a simple C/C++ application and put the
source file into the directory of the test cases. The test suit will automatically pick the
file up and generate a test case from it in run time (with name test_standard_unwind_<file_name>
after escaping some special characters).
"""

from __future__ import print_function


import unittest2
import os
import time
import lldb
from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
from lldbsuite.test import lldbutil

test_source_dirs = ["."]


class StandardUnwindTest(TestBase):
    mydir = TestBase.compute_mydir(__file__)

    def standard_unwind_tests(self):
        # The following variables have to be defined for each architecture and OS we testing for:
        # base_function_names: List of function names where we accept that the stack unwinding is
        #                      correct if they are on the stack. It should include the bottom most
        #                      function on the stack and a list of functions where we know we can't
        #                      unwind for any reason (list of expected failure functions)
        # no_step_function_names: The list of functions where we don't want to step through
        #                         instruction by instruction for any reason. (A valid reason is if
        #                         it is impossible to step through a function instruction by
        #                         instruction because it is special for some reason.) For these
        # functions we will immediately do a step-out when we hit them.

        triple = self.dbg.GetSelectedPlatform().GetTriple()
        if re.match("arm-.*-.*-android", triple):
            base_function_names = [
                "_start",                # Base function on the stack
                "__memcpy_base",         # Function reached by a fall through from the previous function
                "__memcpy_base_aligned",
                # Function reached by a fall through from the previous function
            ]
            no_step_function_names = [
                "__sync_fetch_and_add_4",  # Calls into a special SO where we can't set a breakpoint
                "pthread_mutex_lock",
                # Uses ldrex and strex what interferes with the software single
                # stepping
                "pthread_mutex_unlock",
                # Uses ldrex and strex what interferes with the software single
                # stepping
                "pthread_once",
                # Uses ldrex and strex what interferes with the software single
                # stepping
            ]
        elif re.match("aarch64-.*-.*-android", triple):
            base_function_names = [
                "do_arm64_start",         # Base function on the stack
            ]
            no_step_function_names = [
                None,
                "__cxa_guard_acquire",
                # Uses ldxr and stxr what interferes with the software single
                # stepping
                "__cxa_guard_release",
                # Uses ldxr and stxr what interferes with the software single
                # stepping
                "pthread_mutex_lock",
                # Uses ldxr and stxr what interferes with the software single
                # stepping
                "pthread_mutex_unlock",
                # Uses ldxr and stxr what interferes with the software single
                # stepping
                "pthread_once",
                # Uses ldxr and stxr what interferes with the software single
                # stepping
            ]
        else:
            self.skipTest("No expectations for the current architecture")

        exe = self.getBuildArtifact("a.out")
        target = self.dbg.CreateTarget(exe)
        self.assertTrue(target, VALID_TARGET)

        target.BreakpointCreateByName("main")

        process = target.LaunchSimple(
            None, None, self.get_process_working_directory())
        self.assertTrue(process is not None, "SBTarget.Launch() failed")
        self.assertEqual(
            process.GetState(),
            lldb.eStateStopped,
            "The process didn't hit main")

        index = 0
        while process.GetState() == lldb.eStateStopped:
            index += 1
            if process.GetNumThreads() > 1:
                # In case of a multi threaded inferior if one of the thread is stopped in a blocking
                # syscall and we try to step it then
                # SBThread::StepInstruction() will block forever
                self.skipTest(
                    "Multi threaded inferiors are not supported by this test")

            thread = process.GetThreadAtIndex(0)

            if self.TraceOn():
                print("INDEX: %u" % index)
                for f in thread.frames:
                    print(f)

            if thread.GetFrameAtIndex(0).GetFunctionName() is not None:
                found_main = False
                for f in thread.frames:
                    if f.GetFunctionName() in base_function_names:
                        found_main = True
                        break
                self.assertTrue(found_main,
                                "Main function isn't found on the backtrace")

            if thread.GetFrameAtIndex(
                    0).GetFunctionName() in no_step_function_names:
                thread.StepOut()
            else:
                thread.StepInstruction(False)

# Collect source files in the specified directories
test_source_files = set([])
for d in test_source_dirs:
    if os.path.isabs(d):
        dirname = d
    else:
        dirname = os.path.join(os.path.dirname(__file__), d)

    for root, _, files in os.walk(dirname):
        test_source_files = test_source_files | set(
            os.path.abspath(os.path.join(root, f)) for f in files)

# Generate test cases based on the collected source files
for f in test_source_files:
    if f.endswith(".cpp") or f.endswith(".c"):
        @add_test_categories(["dwarf"])
        @unittest2.skipIf(
            TestBase.skipLongRunningTest(),
            "Skip this long running test")
        def test_function_dwarf(self, f=f):
            if f.endswith(".cpp"):
                d = {'CXX_SOURCES': f}
            elif f.endswith(".c"):
                d = {'C_SOURCES': f}

            # If we can't compile the inferior just skip the test instead of failing it.
            # It makes the test suit more robust when testing on several different architecture
            # avoid the hassle of skipping tests manually.
            try:
                self.buildDwarf(dictionary=d)
                self.setTearDownCleanup(d)
            except:
                if self.TraceOn():
                    print(sys.exc_info()[0])
                self.skipTest("Inferior not supported")
            self.standard_unwind_tests()

        test_name = "test_unwind_" + str(f)
        for c in ".=()/\\":
            test_name = test_name.replace(c, '_')

        test_function_dwarf.__name__ = test_name
        setattr(
            StandardUnwindTest,
            test_function_dwarf.__name__,
            test_function_dwarf)
