# Copyright (C) 2019-2023 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/>.

import gdb


class BadKey:
    def __repr__(self):
        return "Bad Key"


class ReallyBadKey:
    def __repr__(self):
        return BadKey()


class pycmd1(gdb.MICommand):
    def invoke(self, argv):
        if argv[0] == "int":
            return {"result": 42}
        elif argv[0] == "str":
            return {"result": "Hello world!"}
        elif argv[0] == "ary":
            return {"result": ["Hello", 42]}
        elif argv[0] == "dct":
            return {"result": {"hello": "world", "times": 42}}
        elif argv[0] == "bk1":
            return {"result": {BadKey(): "world"}}
        elif argv[0] == "bk2":
            return {"result": {1: "world"}}
        elif argv[0] == "bk3":
            return {"result": {ReallyBadKey(): "world"}}
        elif argv[0] == "tpl":
            return {"result": (42, "Hello")}
        elif argv[0] == "itr":
            return {"result": iter([1, 2, 3])}
        elif argv[0] == "nn1":
            return None
        elif argv[0] == "nn2":
            return {"result": [None]}
        elif argv[0] == "red":
            pycmd2("-pycmd")
            return None
        elif argv[0] == "nd1":
            return [1, 2, 3]
        elif argv[0] == "nd2":
            return 123
        elif argv[0] == "nd3":
            return "abc"
        elif argv[0] == "ik1":
            return {"xxx yyy": 123}
        elif argv[0] == "ik2":
            return {"result": {"xxx yyy": 123}}
        elif argv[0] == "ik3":
            return {"xxx+yyy": 123}
        elif argv[0] == "ik4":
            return {"xxx.yyy": 123}
        elif argv[0] == "ik5":
            return {"123xxxyyy": 123}
        elif argv[0] == "empty_key":
            return {"": 123}
        elif argv[0] == "dash-key":
            return {"the-key": 123}
        elif argv[0] == "exp":
            raise gdb.GdbError()
        else:
            raise gdb.GdbError("Invalid parameter: %s" % argv[0])


class pycmd2(gdb.MICommand):
    def invoke(self, argv):
        if argv[0] == "str":
            return {"result": "Ciao!"}
        elif argv[0] == "red":
            pycmd1("-pycmd")
            raise gdb.GdbError("Command redefined but we failing anyway")
        elif argv[0] == "new":
            pycmd1("-pycmd-new")
            return None
        else:
            raise gdb.GdbError("Invalid parameter: %s" % argv[0])


# This class creates a command that returns a string, which is passed
# when the command is created.
class pycmd3(gdb.MICommand):
    def __init__(self, name, msg, top_level):
        super(pycmd3, self).__init__(name)
        self._msg = msg
        self._top_level = top_level

    def invoke(self, args):
        return {self._top_level: {"msg": self._msg}}


# A command that is missing it's invoke method.
class no_invoke(gdb.MICommand):
    def __init__(self, name):
        super(no_invoke, self).__init__(name)


def free_invoke(obj, args):
    return {"result": args}


# Run some test involving catching exceptions.  It's easier to write
# these as a Python function which is then called from the exp script.
def run_exception_tests():
    print("PASS")


# Run some execute_mi tests.  This is easier to do from Python.
def run_execute_mi_tests():
    # Install the command.
    cmd = pycmd1("-pycmd")
    # Pass in a representative subset of the pycmd1 keys, and then
    # check that the result via MI is the same as the result via a
    # direct Python call.  Note that some results won't compare as
    # equal -- for example, a Python MI command can return a tuple,
    # but that will be translated to a Python list.
    for name in ("int", "str", "dct"):
        expect = cmd.invoke([name])
        got = gdb.execute_mi("-pycmd", name)
        if expect != got:
            print("FAIL: saw " + repr(got) + ", but expected " + repr(expect))
            return
    ok = False
    try:
        gdb.execute_mi("-pycmd", "exp")
    # Due to the "denaturation" problem, we have to expect a gdb.error
    # here and not a gdb.GdbError.
    except gdb.error:
        ok = True
    if not ok:
        print("FAIL: did not throw exception")
    print("PASS")
