# Frame-filter commands.
# Copyright (C) 2013-2016 Free Software Foundation, Inc.

# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# This program 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 General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.

"""GDB commands for working with frame-filters."""

import sys
import gdb
import copy
from gdb.FrameIterator import FrameIterator
from gdb.FrameDecorator import FrameDecorator
import gdb.frames
import itertools

# GDB Commands.
class SetFilterPrefixCmd(gdb.Command):
    """Prefix command for 'set' frame-filter related operations."""

    def __init__(self):
        super(SetFilterPrefixCmd, self).__init__("set frame-filter",
                                                 gdb.COMMAND_OBSCURE,
                                                 gdb.COMPLETE_NONE, True)

class ShowFilterPrefixCmd(gdb.Command):
    """Prefix command for 'show' frame-filter related operations."""
    def __init__(self):
        super(ShowFilterPrefixCmd, self).__init__("show frame-filter",
                                                  gdb.COMMAND_OBSCURE,
                                                  gdb.COMPLETE_NONE, True)
class InfoFrameFilter(gdb.Command):
    """List all registered Python frame-filters.

    Usage: info frame-filters
    """

    def __init__(self):
        super(InfoFrameFilter, self).__init__("info frame-filter",
                                              gdb.COMMAND_DATA)
    @staticmethod
    def enabled_string(state):
        """Return "Yes" if filter is enabled, otherwise "No"."""
        if state:
            return "Yes"
        else:
            return "No"

    def list_frame_filters(self, frame_filters):
        """ Internal worker function to list and print frame filters
        in a dictionary.

        Arguments:
           frame_filters: The name of the dictionary, as
           specified by GDB user commands.
        """

        sorted_frame_filters = sorted(frame_filters.items(),
                                      key=lambda i: gdb.frames.get_priority(i[1]),
                                      reverse=True)

        if len(sorted_frame_filters) == 0:
            print("  No frame filters registered.")
        else:
            print("  Priority  Enabled  Name")
            for frame_filter in sorted_frame_filters:
                name = frame_filter[0]
                try:
                    priority = '{:<8}'.format(
                        str(gdb.frames.get_priority(frame_filter[1])))
                    enabled = '{:<7}'.format(
                        self.enabled_string(gdb.frames.get_enabled(frame_filter[1])))
                except Exception:
                    e = sys.exc_info()[1]
                    print("  Error printing filter '"+name+"': "+str(e))
                else:
                    print("  %s  %s  %s" % (priority, enabled, name))

    def print_list(self, title, filter_list, blank_line):
        print(title)
        self.list_frame_filters(filter_list)
        if blank_line:
            print("")

    def invoke(self, arg, from_tty):
        self.print_list("global frame-filters:", gdb.frame_filters, True)

        cp = gdb.current_progspace()
        self.print_list("progspace %s frame-filters:" % cp.filename,
                        cp.frame_filters, True)

        for objfile in gdb.objfiles():
            self.print_list("objfile %s frame-filters:" % objfile.filename,
                            objfile.frame_filters, False)

# Internal enable/disable functions.

def _enable_parse_arg(cmd_name, arg):
    """ Internal worker function to take an argument from
    enable/disable and return a tuple of arguments.

    Arguments:
        cmd_name: Name of the command invoking this function.
        args: The argument as a string.

    Returns:
        A tuple containing the dictionary, and the argument, or just
        the dictionary in the case of "all".
    """

    argv = gdb.string_to_argv(arg);
    argc = len(argv)
    if argv[0] == "all" and argc > 1:
        raise gdb.GdbError(cmd_name + ": with 'all' " \
                          "you may not specify a filter.")
    else:
        if argv[0] != "all" and argc != 2:
            raise gdb.GdbError(cmd_name + " takes exactly two arguments.")

    return argv

def _do_enable_frame_filter(command_tuple, flag):
    """Worker for enabling/disabling frame_filters.

    Arguments:
        command_type: A tuple with the first element being the
                      frame filter dictionary, and the second being
                      the frame filter name.
        flag: True for Enable, False for Disable.
    """

    list_op = command_tuple[0]
    op_list = gdb.frames.return_list(list_op)

    if list_op == "all":
        for item in op_list:
            gdb.frames.set_enabled(item, flag)
    else:
        frame_filter = command_tuple[1]
        try:
            ff = op_list[frame_filter]
        except KeyError:
            msg = "frame-filter '" + str(name) + "' not found."
            raise gdb.GdbError(msg)

        gdb.frames.set_enabled(ff, flag)

def _complete_frame_filter_list(text, word, all_flag):
    """Worker for frame filter dictionary name completion.

    Arguments:
        text: The full text of the command line.
        word: The most recent word of the command line.
        all_flag: Whether to include the word "all" in completion.

    Returns:
        A list of suggested frame filter dictionary name completions
        from text/word analysis.  This list can be empty when there
        are no suggestions for completion.
        """
    if all_flag == True:
        filter_locations = ["all", "global", "progspace"]
    else:
        filter_locations = ["global", "progspace"]
    for objfile in gdb.objfiles():
        filter_locations.append(objfile.filename)

    # If the user just asked for completions with no completion
    # hints, just return all the frame filter dictionaries we know
    # about.
    if (text == ""):
        return filter_locations

    # Otherwise filter on what we know.
    flist = filter(lambda x,y=text:x.startswith(y), filter_locations)

    # If we only have one completion, complete it and return it.
    if len(flist) == 1:
        flist[0] = flist[0][len(text)-len(word):]

    # Otherwise, return an empty list, or a list of frame filter
    # dictionaries that the previous filter operation returned.
    return flist

def _complete_frame_filter_name(word, printer_dict):
    """Worker for frame filter name completion.

    Arguments:

        word: The most recent word of the command line.

        printer_dict: The frame filter dictionary to search for frame
        filter name completions.

        Returns: A list of suggested frame filter name completions
        from word analysis of the frame filter dictionary.  This list
        can be empty when there are no suggestions for completion.
    """

    printer_keys = printer_dict.keys()
    if (word == ""):
        return printer_keys

    flist = filter(lambda x,y=word:x.startswith(y), printer_keys)
    return flist

class EnableFrameFilter(gdb.Command):
    """GDB command to disable the specified frame-filter.

    Usage: enable frame-filter enable DICTIONARY [NAME]

    DICTIONARY is the name of the frame filter dictionary on which to
    operate.  If dictionary is set to "all", perform operations on all
    dictionaries.  Named dictionaries are: "global" for the global
    frame filter dictionary, "progspace" for the program space's frame
    filter dictionary.  If either all, or the two named dictionaries
    are not specified, the dictionary name is assumed to be the name
    of the object-file name.

    NAME matches the name of the frame-filter to operate on.  If
    DICTIONARY is "all", NAME is ignored.
    """
    def __init__(self):
        super(EnableFrameFilter, self).__init__("enable frame-filter",
                                                 gdb.COMMAND_DATA)
    def complete(self, text, word):
        """Completion function for both frame filter dictionary, and
        frame filter name."""
        if text.count(" ") == 0:
            return _complete_frame_filter_list(text, word, True)
        else:
            printer_list = gdb.frames.return_list(text.split()[0].rstrip())
            return _complete_frame_filter_name(word, printer_list)

    def invoke(self, arg, from_tty):
        command_tuple = _enable_parse_arg("enable frame-filter", arg)
        _do_enable_frame_filter(command_tuple, True)


class DisableFrameFilter(gdb.Command):
    """GDB command to disable the specified frame-filter.

    Usage: disable frame-filter disable DICTIONARY [NAME]

    DICTIONARY is the name of the frame filter dictionary on which to
    operate.  If dictionary is set to "all", perform operations on all
    dictionaries.  Named dictionaries are: "global" for the global
    frame filter dictionary, "progspace" for the program space's frame
    filter dictionary.  If either all, or the two named dictionaries
    are not specified, the dictionary name is assumed to be the name
    of the object-file name.

    NAME matches the name of the frame-filter to operate on.  If
    DICTIONARY is "all", NAME is ignored.
    """
    def __init__(self):
        super(DisableFrameFilter, self).__init__("disable frame-filter",
                                                  gdb.COMMAND_DATA)

    def complete(self, text, word):
        """Completion function for both frame filter dictionary, and
        frame filter name."""
        if text.count(" ") == 0:
            return _complete_frame_filter_list(text, word, True)
        else:
            printer_list = gdb.frames.return_list(text.split()[0].rstrip())
            return _complete_frame_filter_name(word, printer_list)

    def invoke(self, arg, from_tty):
        command_tuple = _enable_parse_arg("disable frame-filter", arg)
        _do_enable_frame_filter(command_tuple, False)

class SetFrameFilterPriority(gdb.Command):
    """GDB command to set the priority of the specified frame-filter.

    Usage: set frame-filter priority DICTIONARY NAME PRIORITY

    DICTIONARY is the name of the frame filter dictionary on which to
    operate.  Named dictionaries are: "global" for the global frame
    filter dictionary, "progspace" for the program space's framefilter
    dictionary.  If either of these two are not specified, the
    dictionary name is assumed to be the name of the object-file name.

    NAME matches the name of the frame filter to operate on.

    PRIORITY is the an integer to assign the new priority to the frame
    filter.
    """

    def __init__(self):
        super(SetFrameFilterPriority, self).__init__("set frame-filter " \
                                                     "priority",
                                                     gdb.COMMAND_DATA)

    def _parse_pri_arg(self, arg):
        """Internal worker to parse a priority from a tuple.

        Arguments:
            arg: Tuple which contains the arguments from the command.

        Returns:
            A tuple containing the dictionary, name and priority from
            the arguments.

        Raises:
            gdb.GdbError: An error parsing the arguments.
        """

        argv = gdb.string_to_argv(arg);
        argc = len(argv)
        if argc != 3:
            print("set frame-filter priority " \
                  "takes exactly three arguments.")
            return None

        return argv

    def _set_filter_priority(self, command_tuple):
        """Internal worker for setting priority of frame-filters, by
        parsing a tuple and calling _set_priority with the parsed
        tuple.

        Arguments:
            command_tuple: Tuple which contains the arguments from the
                           command.
        """

        list_op = command_tuple[0]
        frame_filter = command_tuple[1]

        # GDB returns arguments as a string, so convert priority to
        # a number.
        priority = int(command_tuple[2])

        op_list = gdb.frames.return_list(list_op)

        try:
            ff = op_list[frame_filter]
        except KeyError:
            msg = "frame-filter '" + str(name) + "' not found."
            raise gdb.GdbError(msg)

        gdb.frames.set_priority(ff, priority)

    def complete(self, text, word):
        """Completion function for both frame filter dictionary, and
        frame filter name."""
        if text.count(" ") == 0:
            return _complete_frame_filter_list(text, word, False)
        else:
            printer_list = gdb.frames.return_list(text.split()[0].rstrip())
            return _complete_frame_filter_name(word, printer_list)

    def invoke(self, arg, from_tty):
        command_tuple = self._parse_pri_arg(arg)
        if command_tuple != None:
            self._set_filter_priority(command_tuple)

class ShowFrameFilterPriority(gdb.Command):
    """GDB command to show the priority of the specified frame-filter.

    Usage: show frame-filter priority DICTIONARY NAME

    DICTIONARY is the name of the frame filter dictionary on which to
    operate.  Named dictionaries are: "global" for the global frame
    filter dictionary, "progspace" for the program space's framefilter
    dictionary.  If either of these two are not specified, the
    dictionary name is assumed to be the name of the object-file name.

    NAME matches the name of the frame-filter to operate on.
    """

    def __init__(self):
        super(ShowFrameFilterPriority, self).__init__("show frame-filter " \
                                                      "priority",
                                                      gdb.COMMAND_DATA)

    def _parse_pri_arg(self, arg):
        """Internal worker to parse a dictionary and name from a
        tuple.

        Arguments:
            arg: Tuple which contains the arguments from the command.

        Returns:
            A tuple containing the dictionary,  and frame filter name.

        Raises:
            gdb.GdbError: An error parsing the arguments.
        """

        argv = gdb.string_to_argv(arg);
        argc = len(argv)
        if argc != 2:
            print("show frame-filter priority " \
                  "takes exactly two arguments.")
            return None

        return argv

    def get_filter_priority(self, frame_filters, name):
        """Worker for retrieving the priority of frame_filters.

        Arguments:
            frame_filters: Name of frame filter dictionary.
            name: object to select printers.

        Returns:
            The priority of the frame filter.

        Raises:
            gdb.GdbError: A frame filter cannot be found.
        """

        op_list = gdb.frames.return_list(frame_filters)

        try:
            ff = op_list[name]
        except KeyError:
            msg = "frame-filter '" + str(name) + "' not found."
            raise gdb.GdbError(msg)

        return gdb.frames.get_priority(ff)

    def complete(self, text, word):
        """Completion function for both frame filter dictionary, and
        frame filter name."""

        if text.count(" ") == 0:
            return _complete_frame_filter_list(text, word, False)
        else:
            printer_list = frame._return_list(text.split()[0].rstrip())
            return _complete_frame_filter_name(word, printer_list)

    def invoke(self, arg, from_tty):
        command_tuple = self._parse_pri_arg(arg)
        if command_tuple == None:
            return
        filter_name = command_tuple[1]
        list_name = command_tuple[0]
        try:
            priority = self.get_filter_priority(list_name, filter_name);
        except Exception:
            e = sys.exc_info()[1]
            print("Error printing filter priority for '"+name+"':"+str(e))
        else:
            print("Priority of filter '" + filter_name + "' in list '" \
                + list_name + "' is: " + str(priority))

# Register commands
SetFilterPrefixCmd()
ShowFilterPrefixCmd()
InfoFrameFilter()
EnableFrameFilter()
DisableFrameFilter()
SetFrameFilterPriority()
ShowFrameFilterPriority()
