# Frame-filter commands.
# Copyright (C) 2013 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 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 as e:
                    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]
        priority = 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 as e:
            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()
