"""Test the go dynamic type handling."""

import os, time
import unittest2
import lldb
import lldbutil
from lldbtest import *

class TestGoLanguageRuntime(TestBase):

    mydir = TestBase.compute_mydir(__file__)

    @python_api_test
    @expectedFailureAll(oslist=['freebsd'], bugnumber='llvm.org/pr24895')
    @skipIfRemote # Not remote test suite ready
    @skipUnlessGoInstalled
    def test_with_dsym_and_python_api(self):
        """Test GoASTContext dwarf parsing."""
        self.buildGo()
        self.launchProcess()
        self.go_interface_types()

    def setUp(self):
        # Call super's setUp().
        TestBase.setUp(self)
        # Find the line numbers to break inside main().
        self.main_source = "main.go"
        self.break_line1 = line_number(self.main_source, '// Set breakpoint 1')
        self.break_line2 = line_number(self.main_source, '// Set breakpoint 2')


    def launchProcess(self):
        exe = self.getBuildArtifact("a.out")

        target = self.dbg.CreateTarget(exe)
        self.assertTrue(target, VALID_TARGET)

        bpt1 = target.BreakpointCreateByLocation(self.main_source, self.break_line1)
        self.assertTrue(bpt1, VALID_BREAKPOINT)
        bpt2 = target.BreakpointCreateByLocation(self.main_source, self.break_line2)
        self.assertTrue(bpt2, VALID_BREAKPOINT)

        # Now launch the process, and do not stop at entry point.
        process = target.LaunchSimple (None, None, self.get_process_working_directory())

        self.assertTrue(process, PROCESS_IS_VALID)

        # The stop reason of the thread should be breakpoint.
        thread_list = lldbutil.get_threads_stopped_at_breakpoint (process, bpt1)

        # Make sure we stopped at the first breakpoint.
        self.assertTrue (len(thread_list) != 0, "No thread stopped at our breakpoint.")
        self.assertTrue (len(thread_list) == 1, "More than one thread stopped at our breakpoint.")

        frame = thread_list[0].GetFrameAtIndex(0)
        self.assertTrue (frame, "Got a valid frame 0 frame.")

    def go_interface_types(self):
        f = self.frame()
        v = f.FindVariable("a", lldb.eDynamicCanRunTarget)
        self.assertEqual("*int", v.GetType().name)
        self.assertEqual(1, v.Dereference().GetValueAsSigned())
        v = f.FindVariable("b", lldb.eDynamicCanRunTarget)
        self.assertEqual("*float64", v.GetType().name)
        err = lldb.SBError()
        self.assertEqual(2.0, v.Dereference().GetData().GetDouble(err, 0))
        v = f.FindVariable("c", lldb.eDynamicCanRunTarget)
        self.assertEqual("*main.SomeFooer", v.GetType().name)
        self.assertEqual(9, v.Dereference().GetChildAtIndex(0).GetValueAsSigned())
        v = f.FindVariable("d", lldb.eDynamicCanRunTarget)
        self.assertEqual("*main.AnotherFooer", v.GetType().name)
        self.assertEqual(-1, v.Dereference().GetChildAtIndex(0).GetValueAsSigned())
        self.assertEqual(-2, v.Dereference().GetChildAtIndex(1).GetValueAsSigned())
        self.assertEqual(-3, v.Dereference().GetChildAtIndex(2).GetValueAsSigned())

if __name__ == '__main__':
    import atexit
    lldb.SBDebugger.Initialize()
    atexit.register(lambda: lldb.SBDebugger.Terminate())
    unittest2.main()
