# Copyright (C) 2024-2025 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 os
import shutil
from enum import Enum

import gdb
from gdb.missing_objfile import MissingObjfileHandler

# A global log that is filled in by instances of the LOG_HANDLER class
# when they are called.
handler_call_log = []

# A global holding a string, the build-id of the last missing objfile
# which triggered the 'handler' class below.  This is set in the
# __call__ method of the 'handler' class and then checked from the
# expect script.
handler_last_buildid = None


# A global holding a string, the filename of the last missing objfile
# which triggered the 'handler' class below.  This is set in the
# __call__ method of the 'handler' class and then checked from the
# expect script.
handler_last_filename = None


# A helper function that makes some assertions about the arguments
# passed to a MissingObjfileHandler.__call__() method.
def check_args(pspace, buildid, filename):
    assert type(filename) == str
    assert filename != ""
    assert type(pspace) == gdb.Progspace
    assert type(buildid) == str
    assert buildid != ""


# Enum used to configure the 'handler' class from the test script.
class Mode(Enum):
    RETURN_NONE = 0
    RETURN_TRUE = 1
    RETURN_FALSE = 2
    RETURN_STRING = 3


# A missing objfile handler which can be configured to return each of
# the different possible return types.
class handler(MissingObjfileHandler):
    def __init__(self):
        super().__init__("handler")
        self._call_count = 0
        self._mode = Mode.RETURN_NONE

    def __call__(self, pspace, buildid, filename):
        global handler_call_log, handler_last_buildid, handler_last_filename
        check_args(pspace, buildid, filename)
        handler_call_log.append(self.name)
        handler_last_buildid = buildid
        handler_last_filename = filename
        self._call_count += 1
        if self._mode == Mode.RETURN_NONE:
            return None

        if self._mode == Mode.RETURN_TRUE:
            shutil.copy(self._src, self._dest)

            # If we're using the fission-dwp board then there will
            # also be a .dwp file that needs to be copied.
            dwp_src = self._src + ".dwp"
            if os.path.exists(dwp_src):
                dwp_dest = self._dest + ".dwp"
                shutil.copy(dwp_src, dwp_dest)

            return True

        if self._mode == Mode.RETURN_FALSE:
            return False

        if self._mode == Mode.RETURN_STRING:
            return self._dest

        assert False

    @property
    def call_count(self):
        """Return a count, the number of calls to __call__ since the last
        call to set_mode.
        """
        return self._call_count

    def set_mode(self, mode, *args):
        self._call_count = 0
        self._mode = mode

        if mode == Mode.RETURN_NONE:
            assert len(args) == 0
            return

        if mode == Mode.RETURN_TRUE:
            assert len(args) == 2
            self._src = args[0]
            self._dest = args[1]
            return

        if mode == Mode.RETURN_FALSE:
            assert len(args) == 0
            return

        if mode == Mode.RETURN_STRING:
            assert len(args) == 1
            self._dest = args[0]
            return

        assert False


# A missing objfile handler which raises an exception.  The type of
# exception to be raised is configured from the test script.
class exception_handler(MissingObjfileHandler):
    def __init__(self):
        super().__init__("exception_handler")
        self.exception_type = None

    def __call__(self, pspace, buildid, filename):
        global handler_call_log
        check_args(pspace, buildid, filename)
        handler_call_log.append(self.name)
        assert self.exception_type is not None
        raise self.exception_type("message")


# A very simple logging missing objfile handler.  Always returns None
# so that GDB will try any other registered handlers, but first logs
# the name of this handler into the global HANDLER_CALL_LOG, which can
# then be checked from the test script.
class log_handler(MissingObjfileHandler):
    def __call__(self, pspace, buildid, filename):
        global handler_call_log
        check_args(pspace, buildid, filename)
        handler_call_log.append(self.name)
        return None


# A basic helper function, this keeps lines shorter in the TCL script.
def register(name, locus=None):
    gdb.missing_objfile.register_handler(locus, log_handler(name))


# Create instances of the handlers, but don't install any.  We install
# these as needed from the TCL script.
rhandler = exception_handler()
handler_obj = handler()

print("Success")
