"""Check that compiler-generated register values work correctly"""

from __future__ import print_function

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

# This method attempts to figure out if a given variable
# is in a register.
#
# Return:
#   True if the value has a readable value and is in a register
#   False otherwise


def is_variable_in_register(frame, var_name):
    # Ensure we can lookup the variable.
    var = frame.FindVariable(var_name)
    # print("\nchecking {}...".format(var_name))
    if var is None or not var.IsValid():
        # print("{} cannot be found".format(var_name))
        return False

    # Check that we can get its value.  If not, this
    # may be a variable that is just out of scope at this point.
    value = var.GetValue()
    # print("checking value...")
    if value is None:
        # print("value is invalid")
        return False
    # else:
        # print("value is {}".format(value))

    # We have a variable and we can get its value.  The variable is in
    # a register if we cannot get an address for it, assuming it is
    # not a struct pointer.  (This is an approximation - compilers can
    # do other things with spitting up a value into multiple parts of
    # multiple registers, but what we're verifying here is much more
    # than it was doing before).
    var_addr = var.GetAddress()
    # print("checking address...")
    if var_addr.IsValid():
        # We have an address, it must not be in a register.
        # print("var {} is not in a register: has a valid address {}".format(var_name, var_addr))
        return False
    else:
        # We don't have an address but we can read the value.
        # It is likely stored in a register.
        # print("var {} is in a register (we don't have an address for it)".format(var_name))
        return True


def is_struct_pointer_in_register(frame, var_name, trace):
    # Ensure we can lookup the variable.
    var = frame.FindVariable(var_name)
    if trace:
        print("\nchecking {}...".format(var_name))

    if var is None or not var.IsValid():
        # print("{} cannot be found".format(var_name))
        return False

    # Check that we can get its value.  If not, this
    # may be a variable that is just out of scope at this point.
    value = var.GetValue()
    # print("checking value...")
    if value is None:
        if trace:
            print("value is invalid")
        return False
    else:
        if trace:
             print("value is {}".format(value))

    var_loc = var.GetLocation()
    if trace:
        print("checking location: {}".format(var_loc))
    if var_loc is None or var_loc.startswith("0x"):
        # The frame var is not in a register but rather a memory location.
        # print("frame var {} is not in a register".format(var_name))
        return False
    else:
        # print("frame var {} is in a register".format(var_name))
        return True


def re_expr_equals(val_type, val):
    # Match ({val_type}) ${sum_digits} = {val}
    return re.compile(r'\(' + val_type + '\) \$\d+ = ' + str(val))


class RegisterVariableTestCase(TestBase):

    mydir = TestBase.compute_mydir(__file__)

    @expectedFailureAll(compiler="clang", compiler_version=['<', '3.5'])
    @expectedFailureAll(compiler="gcc", compiler_version=[
            '>=', '4.8.2'], archs=["i386"])
    @expectedFailureAll(compiler="gcc", compiler_version=[
            '<', '4.9'], archs=["x86_64"])
    def test_and_run_command(self):
        """Test expressions on register values."""

        # This test now ensures that each probable
        # register variable location is actually a register, and
        # if so, whether we can print out the variable there.
        # It only requires one of them to be handled in a non-error
        # way.
        register_variables_count = 0

        self.build()
        exe = self.getBuildArtifact("a.out")
        self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)

        # Break inside the main.
        lldbutil.run_break_set_by_source_regexp(
            self, "break", num_expected_locations=3)

        ####################
        # First breakpoint

        self.runCmd("run", RUN_SUCCEEDED)

        # The stop reason of the thread should be breakpoint.
        self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
                    substrs=['stopped',
                             'stop reason = breakpoint'])

        # The breakpoint should have a hit count of 1.
        self.expect("breakpoint list -f", BREAKPOINT_HIT_ONCE,
                    substrs=[' resolved, hit count = 1'])

        # Try some variables that should be visible
        frame = self.dbg.GetSelectedTarget().GetProcess(
        ).GetSelectedThread().GetSelectedFrame()
        if is_variable_in_register(frame, 'a'):
            register_variables_count += 1
            self.expect("expr a", VARIABLES_DISPLAYED_CORRECTLY,
                        patterns=[re_expr_equals('int', 2)])

        if is_struct_pointer_in_register(frame, 'b', self.TraceOn()):
            register_variables_count += 1
            self.expect("expr b->m1", VARIABLES_DISPLAYED_CORRECTLY,
                        patterns=[re_expr_equals('int', 3)])

        #####################
        # Second breakpoint

        self.runCmd("continue")

        # The stop reason of the thread should be breakpoint.
        self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
                    substrs=['stopped',
                             'stop reason = breakpoint'])

        # The breakpoint should have a hit count of 1.
        self.expect("breakpoint list -f", BREAKPOINT_HIT_ONCE,
                    substrs=[' resolved, hit count = 1'])

        # Try some variables that should be visible
        frame = self.dbg.GetSelectedTarget().GetProcess(
        ).GetSelectedThread().GetSelectedFrame()
        if is_struct_pointer_in_register(frame, 'b', self.TraceOn()):
            register_variables_count += 1
            self.expect("expr b->m2", VARIABLES_DISPLAYED_CORRECTLY,
                        patterns=[re_expr_equals('int', 5)])

        if is_variable_in_register(frame, 'c'):
            register_variables_count += 1
            self.expect("expr c", VARIABLES_DISPLAYED_CORRECTLY,
                        patterns=[re_expr_equals('int', 5)])

        #####################
        # Third breakpoint

        self.runCmd("continue")

        # The stop reason of the thread should be breakpoint.
        self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
                    substrs=['stopped',
                             'stop reason = breakpoint'])

        # The breakpoint should have a hit count of 1.
        self.expect("breakpoint list -f", BREAKPOINT_HIT_ONCE,
                    substrs=[' resolved, hit count = 1'])

        # Try some variables that should be visible
        frame = self.dbg.GetSelectedTarget().GetProcess(
        ).GetSelectedThread().GetSelectedFrame()
        if is_variable_in_register(frame, 'f'):
            register_variables_count += 1
            self.expect("expr f", VARIABLES_DISPLAYED_CORRECTLY,
                        patterns=[re_expr_equals('float', '3.1')])

        # Validate that we verified at least one register variable
        self.assertTrue(
            register_variables_count > 0,
            "expected to verify at least one variable in a register")
        # print("executed {} expressions with values in registers".format(register_variables_count))

        self.runCmd("kill")
