"""
Test lldb Python API SBValue::Cast(SBType) for C++ types.
"""

from __future__ import print_function


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


class CppValueCastTestCase(TestBase):

    mydir = TestBase.compute_mydir(__file__)

    @skipIf(bugnumber="llvm.org/PR36714")
    @add_test_categories(['pyapi'])
    def test_value_cast_with_virtual_inheritance(self):
        """Test SBValue::Cast(SBType) API for C++ types with virtual inheritance."""
        self.build(dictionary=self.d_virtual)
        self.setTearDownCleanup(dictionary=self.d_virtual)
        self.do_sbvalue_cast(self.exe_name)

    @add_test_categories(['pyapi'])
    def test_value_cast_with_regular_inheritance(self):
        """Test SBValue::Cast(SBType) API for C++ types with regular inheritance."""
        self.build(dictionary=self.d_regular)
        self.setTearDownCleanup(dictionary=self.d_regular)
        self.do_sbvalue_cast(self.exe_name)

    def setUp(self):
        # Call super's setUp().
        TestBase.setUp(self)

        # Find the line number to break for main.c.
        self.source = 'sbvalue-cast.cpp'
        self.line = line_number(self.source, '// Set breakpoint here.')
        self.exe_name = self.testMethodName
        self.d_virtual = {
            'CXX_SOURCES': self.source,
            'EXE': self.exe_name,
            'CFLAGS_EXTRAS': '-DDO_VIRTUAL_INHERITANCE'}
        self.d_regular = {'CXX_SOURCES': self.source, 'EXE': self.exe_name}

    def do_sbvalue_cast(self, exe_name):
        """Test SBValue::Cast(SBType) API for C++ types."""
        exe = self.getBuildArtifact(exe_name)

        # Create a target from the debugger.

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

        # Set up our breakpoints:

        breakpoint = target.BreakpointCreateByLocation(self.source, self.line)
        self.assertTrue(breakpoint, VALID_BREAKPOINT)

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

        self.assertTrue(process.GetState() == lldb.eStateStopped,
                        PROCESS_STOPPED)

        # Find DerivedA and DerivedB types.
        typeA = target.FindFirstType('DerivedA')
        typeB = target.FindFirstType('DerivedB')
        self.DebugSBType(typeA)
        self.DebugSBType(typeB)
        self.assertTrue(typeA)
        self.assertTrue(typeB)
        error = lldb.SBError()

        # First stop is for DerivedA instance.
        threads = lldbutil.get_threads_stopped_at_breakpoint(
            process, breakpoint)
        self.assertTrue(len(threads) == 1)
        thread = threads[0]
        frame0 = thread.GetFrameAtIndex(0)

        tellerA = frame0.FindVariable('teller', lldb.eNoDynamicValues)
        self.DebugSBValue(tellerA)
        self.assertTrue(tellerA.GetChildMemberWithName(
            'm_base_val').GetValueAsUnsigned(error, 0) == 20)

        if self.TraceOn():
            for child in tellerA:
                print("child name:", child.GetName())
                print(child)

        # Call SBValue.Cast() to obtain instanceA.
        instanceA = tellerA.Cast(typeA.GetPointerType())
        self.DebugSBValue(instanceA)

        # Iterate through all the children and print their values.
        if self.TraceOn():
            for child in instanceA:
                print("child name:", child.GetName())
                print(child)
        a_member_val = instanceA.GetChildMemberWithName('m_a_val')
        self.DebugSBValue(a_member_val)
        self.assertTrue(a_member_val.GetValueAsUnsigned(error, 0) == 10)

        # Second stop is for DerivedB instance.
        threads = lldbutil.continue_to_breakpoint(process, breakpoint)
        self.assertTrue(len(threads) == 1)
        thread = threads[0]
        frame0 = thread.GetFrameAtIndex(0)

        tellerB = frame0.FindVariable('teller', lldb.eNoDynamicValues)
        self.DebugSBValue(tellerB)
        self.assertTrue(tellerB.GetChildMemberWithName(
            'm_base_val').GetValueAsUnsigned(error, 0) == 12)

        if self.TraceOn():
            for child in tellerB:
                print("child name:", child.GetName())
                print(child)

        # Call SBValue.Cast() to obtain instanceB.
        instanceB = tellerB.Cast(typeB.GetPointerType())
        self.DebugSBValue(instanceB)

        # Iterate through all the children and print their values.
        if self.TraceOn():
            for child in instanceB:
                print("child name:", child.GetName())
                print(child)
        b_member_val = instanceB.GetChildMemberWithName('m_b_val')
        self.DebugSBValue(b_member_val)
        self.assertTrue(b_member_val.GetValueAsUnsigned(error, 0) == 36)
