# Common functions and variables for testing the Python pretty printers.
#
# Copyright (C) 2016-2018 Free Software Foundation, Inc.
# This file is part of the GNU C Library.
#
# The GNU C Library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
#
# The GNU C Library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with the GNU C Library; if not, see
# <http://www.gnu.org/licenses/>.

"""These tests require PExpect 4.0 or newer.

Exported constants:
    PASS, FAIL, UNSUPPORTED (int): Test exit codes, as per evaluate-test.sh.
"""

import os
import re
from test_printers_exceptions import *

PASS = 0
FAIL = 1
UNSUPPORTED = 77

gdb_bin = 'gdb'
gdb_options = '-q -nx'
gdb_invocation = '{0} {1}'.format(gdb_bin, gdb_options)
pexpect_min_version = 4
gdb_min_version = (7, 8)
encoding = 'utf-8'

try:
    import pexpect
except ImportError:
    print('PExpect 4.0 or newer must be installed to test the pretty printers.')
    exit(UNSUPPORTED)

pexpect_version = pexpect.__version__.split('.')[0]

if int(pexpect_version) < pexpect_min_version:
    print('PExpect 4.0 or newer must be installed to test the pretty printers.')
    exit(UNSUPPORTED)

if not pexpect.which(gdb_bin):
    print('gdb 7.8 or newer must be installed to test the pretty printers.')
    exit(UNSUPPORTED)

timeout = 5
TIMEOUTFACTOR = os.environ.get('TIMEOUTFACTOR')

if TIMEOUTFACTOR:
    timeout = int(TIMEOUTFACTOR)

try:
    # Check the gdb version.
    version_cmd = '{0} --version'.format(gdb_invocation, timeout=timeout)
    gdb_version_out = pexpect.run(version_cmd, encoding=encoding)

    # The gdb version string is "GNU gdb <PKGVERSION><version>", where
    # PKGVERSION can be any text.  We assume that there'll always be a space
    # between PKGVERSION and the version number for the sake of the regexp.
    version_match = re.search(r'GNU gdb .* ([1-9]+)\.([0-9]+)', gdb_version_out)

    if not version_match:
        print('The gdb version string (gdb -v) is incorrectly formatted.')
        exit(UNSUPPORTED)

    gdb_version = (int(version_match.group(1)), int(version_match.group(2)))

    if gdb_version < gdb_min_version:
        print('gdb 7.8 or newer must be installed to test the pretty printers.')
        exit(UNSUPPORTED)

    # Check if gdb supports Python.
    gdb_python_cmd = '{0} -ex "python import os" -batch'.format(gdb_invocation,
                                                                timeout=timeout)
    gdb_python_error = pexpect.run(gdb_python_cmd, encoding=encoding)

    if gdb_python_error:
        print('gdb must have python support to test the pretty printers.')
        print('gdb output: {!r}'.format(gdb_python_error))
        exit(UNSUPPORTED)

    # If everything's ok, spawn the gdb process we'll use for testing.
    gdb = pexpect.spawn(gdb_invocation, echo=False, timeout=timeout,
                        encoding=encoding)
    gdb_prompt = u'\(gdb\)'
    gdb.expect(gdb_prompt)

except pexpect.ExceptionPexpect as exception:
    print('Error: {0}'.format(exception))
    exit(FAIL)

def test(command, pattern=None):
    """Sends 'command' to gdb and expects the given 'pattern'.

    If 'pattern' is None, simply consumes everything up to and including
    the gdb prompt.

    Args:
        command (string): The command we'll send to gdb.
        pattern (raw string): A pattern the gdb output should match.

    Returns:
        string: The string that matched 'pattern', or an empty string if
            'pattern' was None.
    """

    match = ''

    gdb.sendline(command)

    if pattern:
        # PExpect does a non-greedy match for '+' and '*'.  Since it can't look
        # ahead on the gdb output stream, if 'pattern' ends with a '+' or a '*'
        # we may end up matching only part of the required output.
        # To avoid this, we'll consume 'pattern' and anything that follows it
        # up to and including the gdb prompt, then extract 'pattern' later.
        index = gdb.expect([u'{0}.+{1}'.format(pattern, gdb_prompt),
                            pexpect.TIMEOUT])

        if index == 0:
            # gdb.after now contains the whole match.  Extract the text that
            # matches 'pattern'.
            match = re.match(pattern, gdb.after, re.DOTALL).group()
        elif index == 1:
            # We got a timeout exception.  Print information on what caused it
            # and bail out.
            error = ('Response does not match the expected pattern.\n'
                     'Command: {0}\n'
                     'Expected pattern: {1}\n'
                     'Response: {2}'.format(command, pattern, gdb.before))

            raise pexpect.TIMEOUT(error)
    else:
        # Consume just the the gdb prompt.
        gdb.expect(gdb_prompt)

    return match

def init_test(test_bin, printer_files, printer_names):
    """Loads the test binary file and the required pretty printers to gdb.

    Args:
        test_bin (string): The name of the test binary file.
        pretty_printers (list of strings): A list with the names of the pretty
            printer files.
    """

    # Load all the pretty printer files.  We're assuming these are safe.
    for printer_file in printer_files:
        test('source {0}'.format(printer_file))

    # Disable all the pretty printers.
    test('disable pretty-printer', r'0 of [0-9]+ printers enabled')

    # Enable only the required printers.
    for printer in printer_names:
        test('enable pretty-printer {0}'.format(printer),
             r'[1-9][0-9]* of [1-9]+ printers enabled')

    # Finally, load the test binary.
    test('file {0}'.format(test_bin))

def go_to_main():
    """Executes a gdb 'start' command, which takes us to main."""

    test('start', r'main')

def get_line_number(file_name, string):
    """Returns the number of the line in which 'string' appears within a file.

    Args:
        file_name (string): The name of the file we'll search through.
        string (string): The string we'll look for.

    Returns:
        int: The number of the line in which 'string' appears, starting from 1.
    """
    number = -1

    with open(file_name) as src_file:
        for i, line in enumerate(src_file):
            if string in line:
                number = i + 1
                break

    if number == -1:
        raise NoLineError(file_name, string)

    return number

def break_at(file_name, string, temporary=True, thread=None):
    """Places a breakpoint on the first line in 'file_name' containing 'string'.

    'string' is usually a comment like "Stop here".  Notice this may fail unless
    the comment is placed inline next to actual code, e.g.:

        ...
        /* Stop here */
        ...

    may fail, while:

        ...
        some_func(); /* Stop here */
        ...

    will succeed.

    If 'thread' isn't None, the breakpoint will be set for all the threads.
    Otherwise, it'll be set only for 'thread'.

    Args:
        file_name (string): The name of the file we'll place the breakpoint in.
        string (string): A string we'll look for inside the file.
            We'll place a breakpoint on the line which contains it.
        temporary (bool): Whether the breakpoint should be automatically deleted
            after we reach it.
        thread (int): The number of the thread we'll place the breakpoint for,
            as seen by gdb.  If specified, it should be greater than zero.
    """

    if not thread:
        thread_str = ''
    else:
        thread_str = 'thread {0}'.format(thread)

    if temporary:
        command = 'tbreak'
        break_type = 'Temporary breakpoint'
    else:
        command = 'break'
        break_type = 'Breakpoint'

    line_number = str(get_line_number(file_name, string))

    test('{0} {1}:{2} {3}'.format(command, file_name, line_number, thread_str),
         r'{0} [0-9]+ at 0x[a-f0-9]+: file {1}, line {2}\.'.format(break_type,
                                                                   file_name,
                                                                   line_number))

def continue_cmd(thread=None):
    """Executes a gdb 'continue' command.

    If 'thread' isn't None, the command will be applied to all the threads.
    Otherwise, it'll be applied only to 'thread'.

    Args:
        thread (int): The number of the thread we'll apply the command to,
            as seen by gdb.  If specified, it should be greater than zero.
    """

    if not thread:
        command = 'continue'
    else:
        command = 'thread apply {0} continue'.format(thread)

    test(command)

def next_cmd(count=1, thread=None):
    """Executes a gdb 'next' command.

    If 'thread' isn't None, the command will be applied to all the threads.
    Otherwise, it'll be applied only to 'thread'.

    Args:
        count (int): The 'count' argument of the 'next' command.
        thread (int): The number of the thread we'll apply the command to,
            as seen by gdb.  If specified, it should be greater than zero.
    """

    if not thread:
        command = 'next'
    else:
        command = 'thread apply {0} next'

    test('{0} {1}'.format(command, count))

def select_thread(thread):
    """Selects the thread indicated by 'thread'.

    Args:
        thread (int): The number of the thread we'll switch to, as seen by gdb.
            This should be greater than zero.
    """

    if thread > 0:
        test('thread {0}'.format(thread))

def get_current_thread_lwpid():
    """Gets the current thread's Lightweight Process ID.

    Returns:
        string: The current thread's LWP ID.
    """

    # It's easier to get the LWP ID through the Python API than the gdb CLI.
    command = 'python print(gdb.selected_thread().ptid[1])'

    return test(command, r'[0-9]+')

def set_scheduler_locking(mode):
    """Executes the gdb 'set scheduler-locking' command.

    Args:
        mode (bool): Whether the scheduler locking mode should be 'on'.
    """
    modes = {
        True: 'on',
        False: 'off'
    }

    test('set scheduler-locking {0}'.format(modes[mode]))

def test_printer(var, to_string, children=None, is_ptr=True):
    """ Tests the output of a pretty printer.

    For a variable called 'var', this tests whether its associated printer
    outputs the expected 'to_string' and children (if any).

    Args:
        var (string): The name of the variable we'll print.
        to_string (raw string): The expected output of the printer's 'to_string'
            method.
        children (map {raw string->raw string}): A map with the expected output
            of the printer's children' method.
        is_ptr (bool): Whether 'var' is a pointer, and thus should be
            dereferenced.
    """

    if is_ptr:
        var = '*{0}'.format(var)

    test('print {0}'.format(var), to_string)

    if children:
        for name, value in children.items():
            # Children are shown as 'name = value'.
            test('print {0}'.format(var), r'{0} = {1}'.format(name, value))

def check_debug_symbol(symbol):
    """ Tests whether a given debugging symbol exists.

    If the symbol doesn't exist, raises a DebugError.

    Args:
        symbol (string): The symbol we're going to check for.
    """

    try:
        test('ptype {0}'.format(symbol), r'type = {0}'.format(symbol))

    except pexpect.TIMEOUT:
        # The symbol doesn't exist.
        raise DebugError(symbol)
