'''
lldbCheckExpect.py

This is a driver script for testing lldb expression evaluation. It installs a
breakpoint command which executes tests inserted by the instrumentation pass,
and launches a target.

To use it, compile a target program with these flags:

    -g -Xfrontend -debugger-testing-transform

Make sure the swift standard library is built with debug info. Then, launch
swift-lldb with "-o path/to/this/script -- <program> [<args>]". There is a
utility available in SWIFT_BINARY_DIR/bin/lldb-check-expect which automates
this, e.g:

    ./bin/lldb-check-expect <program>
    ...
    Evaluating check-expect in closure #2 () -> () in CAPITest.swapTwoValues
      Checked variable: a
      Expected value  : 98
      Actual value    : ...
'''
from __future__ import print_function


def unwrap(s):
    '''
    Strip non-essential character sequences from a string.

    >>> unwrap('(String) value = "42\\\\n"')
    '42'
    >>> unwrap('(Int) $R0 = 42')
    '42'
    >>> unwrap('\\\\"foo\\"')
    'foo'
    >>> unwrap('foo\\nbar')
    'foo\\nbar'
    >>> unwrap(' foo ')
    'foo'
    '''
    s = s[s.find('=') + 1:]
    s = s.lstrip(' "')
    s = s.rstrip('"')
    if s.endswith('\\n'):
        s = s[:-2]
    if s.endswith('\\"'):
        s = s[:-2]
    if s.startswith('\\"'):
        s = s[2:]
    s = s.replace('\\n', '\n')
    s = s.strip()
    return s


def on_check_expect(frame, bp_loc, session):
    parent_frame = frame.get_parent_frame()
    parent_name = parent_frame.GetFunctionName()
    print("Evaluating check-expect in", parent_name)

    # Note: If we fail to stringify the arguments in the check-expect frame,
    # the standard library has probably not been compiled with debug info.
    wrapped_var_name, wrapped_expected_value = map(str, frame.arguments)

    var_name = unwrap(wrapped_var_name)
    expected_value = unwrap(wrapped_expected_value)

    # Evaluate the variable in the parent frame of the check-expect.
    frame.thread.SetSelectedFrame(1)
    expr_result = parent_frame.FindVariable(var_name).GetObjectDescription()
    eval_result = unwrap(str(expr_result))

    print("  Checked variable:", var_name)
    print("  Expected value  :", expected_value)
    print("  Actual value    :", eval_result)

    if eval_result == expected_value:
        # Do not stop execution.
        return False

    print("Found a possible expression evaluation failure.")

    for i, (c1, c2) in enumerate(zip(expected_value, eval_result)):
        if c1 == c2:
            continue
        print(" -> Character difference at index", i)
        print(" -> Expected", c1, "but found", c2)
        break
    else:
        print(" -> Expected string has length", len(expected_value))
        print(" -> Actual string has length", len(eval_result))
    return True


def __lldb_init_module(debugger, internal_dict):
    debugger.HandleCommand('breakpoint set -n _debuggerTestingCheckExpect '
                           '--breakpoint-name check_expect_bkpt')
    debugger.HandleCommand('breakpoint command add --python-function '
                           'lldbCheckExpect.on_check_expect '
                           '--stop-on-error true check_expect_bkpt')
    debugger.HandleCommand('run')
