# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
# See https://llvm.org/LICENSE.txt for license information.
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception

import os
import shutil
import subprocess
import tempfile
from ipykernel.kernelbase import Kernel

__version__ = "0.0.1"


class TableGenKernelException(Exception):
    pass


class TableGenKernel(Kernel):
    """Kernel using llvm-tblgen inside jupyter.

    All input is treated as TableGen unless the first non whitespace character
    is "%" in which case it is a "magic" line.

    The supported cell magic is:
    * %args    - to set the arguments passed to llvm-tblgen.
    * %reset   - to reset the cached code and magic state.
    * %noreset - to not reset the cached code and magic state
                 (useful when you have changed the default to always
                  reset the cache).

    These are "cell magic" meaning it applies to the whole cell. Therefore
    it must be the first line, or part of a run of magic lines starting
    from the first line.

    The following are global magic (that applies to all cells going
    forward):
    * %config  - to change the behaviour of the kernel overall, including
                 changing defaults for things like resets.

    Global magic must be written in the same way as cell magic.

    ```tablgen
    %args
    %reset
    %args --print-records --print-detailed-records
    class Stuff {
      string Name;
    }

    def a_thing : Stuff {}
    ```

    """

    implementation = "tablegen"
    implementation_version = __version__

    language_version = __version__
    language = "tablegen"
    language_info = {
        "name": "tablegen",
        "mimetype": "text/x-tablegen",
        "file_extension": ".td",
        "pygments_lexer": "text",
    }

    def __init__(self, **kwargs):
        Kernel.__init__(self, **kwargs)
        self._executable = None
        # A list of (code, magic) tuples.
        # All the previous cell's code we have run since the last reset.
        # This emulates a persistent state like a Python interpreter would have.
        self._previous_code = ""
        # The most recent set of magic since the last reset.
        self._previous_magic = {}
        # The default cache reset behaviour. True means do not cache anything
        # between cells.
        self._cell_reset = False

    @property
    def banner(self):
        return "llvm-tblgen kernel %s" % __version__

    def get_executable(self):
        """If this is the first run, search for llvm-tblgen.
        Otherwise return the cached path to it."""
        if self._executable is None:
            path = os.environ.get("LLVM_TBLGEN_EXECUTABLE")
            if path is not None and os.path.isfile(path) and os.access(path, os.X_OK):
                self._executable = path
            else:
                path = shutil.which("llvm-tblgen")
                if path is None:
                    raise OSError(
                        "llvm-tblgen not found. Put it on your PATH or set the"
                        " environment variable LLVM_TBLGEN_EXECUTABLE to point to it."
                    )
                self._executable = path

        return self._executable

    def parse_config_magic(self, config):
        """Config should be a list of parameters given to the %config command.
        We allow only one setting per %config line and that setting can only
        have one value.

        Assuming the parameters are valid, update the kernel's setting with
        the new value.

        If there is an error, raise a TableGenKernelException.

        >>> k.parse_config_magic([])
        Traceback (most recent call last):
         ...
        TableGenKernelException: Incorrect number of parameters to %config. Expected %config <setting> <value>.
        >>> k._cell_reset
        False
        >>> k.parse_config_magic(["a", "b", "c"])
        Traceback (most recent call last):
         ...
        TableGenKernelException: Incorrect number of parameters to %config. Expected %config <setting> <value>.
        >>> k.parse_config_magic(["notasetting", "..."])
        Traceback (most recent call last):
         ...
        TableGenKernelException: Unknown kernel setting "notasetting". Possible settings are: "cellreset".
        >>> k.parse_config_magic(["cellreset", "food"])
        Traceback (most recent call last):
         ...
        TableGenKernelException: Invalid value for setting "cellreset", expected "on" or "off".
        >>> k.parse_config_magic(["cellreset", "on"])
        >>> k._cell_reset
        True
        >>> k.parse_config_magic(["cellreset", "off"])
        >>> k._cell_reset
        False
        """
        if len(config) != 2:
            raise TableGenKernelException(
                "Incorrect number of parameters to %config. Expected %config <setting> <value>."
            )

        name, value = config
        if name != "cellreset":
            raise TableGenKernelException(
                'Unknown kernel setting "{}". '
                'Possible settings are: "cellreset".'.format(name)
            )

        try:
            self._cell_reset = {"on": True, "off": False}[value.lower()]
        except KeyError:
            raise TableGenKernelException(
                'Invalid value for setting "{}", '
                'expected "on" or "off".'.format(name)
            )

    def get_magic(self, code):
        """Given a block of code remove the magic lines from it.
        Returns a tuple of newline joined code lines and a dictionary of magic.
        Where the key is the magic name (minus the %) and the values are lists
        of the arguments to the magic.

        Currently we only look for "cell magic" which must be at the start of
        the cell. Meaning the first line, or a set of lines beginning with %
        that come before the first non-magic line.

        >>> k.get_magic("")
        ('', {})
        >>> k.get_magic("Hello World.\\nHello again.")
        ('Hello World.\\nHello again.', {})
        >>> k.get_magic("   %foo a b c")
        ('', {'foo': ['a', 'b', 'c']})
        >>> k.get_magic("%foo\\n   %foo a b c\\nFoo")
        ('Foo', {'foo': ['a', 'b', 'c']})
        >>> k.get_magic("%foo\\n%bar\\nFoo")
        ('Foo', {'foo': [], 'bar': []})
        >>> k.get_magic("Foo\\n%foo\\nFoo")
        ('Foo\\n%foo\\nFoo', {})
        >>> k.get_magic("%bar\\n\\n%foo")
        ('\\n%foo', {'bar': []})
        >>> k.get_magic("%foo a b\\n   Foo\\n%foo c d")
        ('   Foo\\n%foo c d', {'foo': ['a', 'b']})
        >>> k.get_magic("%foo a b\\n \\n%foo c d")
        (' \\n%foo c d', {'foo': ['a', 'b']})
        """
        magic = {}
        code_lines = []

        lines = code.splitlines()
        while lines:
            line = lines.pop(0)
            possible_magic = line.lstrip()
            if possible_magic.startswith("%"):
                magic_parts = possible_magic.split()
                # Key has the % removed
                magic[magic_parts[0][1:]] = magic_parts[1:]
            else:
                code_lines = [line, *lines]
                break

        return "\n".join(code_lines), magic

    def should_reset(self, magic):
        """Return true if we should reset the cache, based on the default
        setting and the current cell's magic %reset and/or %noreset.

        >>> k._cell_reset = False
        >>> k.should_reset({})
        False
        >>> k.should_reset({'reset': [], 'noreset': []})
        Traceback (most recent call last):
        ...
        TableGenKernelException: %reset and %noreset in the same cell is not allowed. Use only one, or neither.
        >>> k.should_reset({'reset': []})
        True
        >>> k.should_reset({'noreset': []})
        False
        >>> k._cell_reset = True
        >>> k.should_reset({})
        True
        >>> k.should_reset({'reset': [], 'noreset': []})
        Traceback (most recent call last):
        ...
        TableGenKernelException: %reset and %noreset in the same cell is not allowed. Use only one, or neither.
        >>> k.should_reset({'reset': []})
        True
        >>> k.should_reset({'noreset': []})
        False
        """
        # Cell reset is the default unless told otherwise.
        should_reset = self._cell_reset
        # Magic reset commands always win if present.
        reset = magic.get("reset") is not None
        noreset = magic.get("noreset") is not None

        if reset and not noreset:
            should_reset = True
        elif noreset and not reset:
            should_reset = False
        elif noreset and reset:
            raise TableGenKernelException(
                "%reset and %noreset in the same cell is not allowed. Use only one, or neither."
            )
        # else neither are set so use the default.

        return should_reset

    def get_code_and_args(self, new_code):
        """Get the code that do_execute should use, taking into account
        the code from any cached cells.

        Returns the code to compile and the arguments to use to do so.

        >>> k._previous_code = ""
        >>> k._previous_magic = {}
        >>> k.get_code_and_args("")
        ('', [])
        >>> k.get_code_and_args("%args 1\\nSome code")
        ('Some code', ['1'])
        >>> k.get_code_and_args("%args 2\\nSome more code")
        ('Some code\\nSome more code', ['2'])
        >>> k.get_code_and_args("%reset\\n%args 3 4\\nSome new code")
        ('Some new code', ['3', '4'])
        >>> k.get_code_and_args("%reset\\nSome new code")
        ('Some new code', [])
        """
        new_code, new_magic = self.get_magic(new_code)

        # Update kernel configuration first, if needed.
        config_magic = new_magic.get("config")
        if config_magic is not None:
            self.parse_config_magic(config_magic)

        if self.should_reset(new_magic):
            self._previous_code = new_code
            self._previous_magic = new_magic
        else:
            self._previous_code += ("\n" if self._previous_code else "") + new_code
            self._previous_magic.update(new_magic)

        return self._previous_code, self._previous_magic.get("args", [])

    def make_status(self):
        return {
            "status": "ok",
            "execution_count": self.execution_count,
            "payload": [],
            "user_expressions": {},
        }

    def send_stream(self, name, content):
        self.send_response(self.iopub_socket, "stream", {"name": name, "text": content})

        return self.make_status()

    def send_stderr(self, stderr):
        return self.send_stream("stderr", stderr)

    def send_stdout(self, stdout):
        return self.send_stream("stdout", stdout)

    def do_execute(
        self, code, silent, store_history=True, user_expressions=None, allow_stdin=False
    ):
        """Execute user code using llvm-tblgen binary."""
        try:
            all_code, args = self.get_code_and_args(code)
        except TableGenKernelException as e:
            return self.send_stderr(str(e))

        # If we cannot find llvm-tblgen, propagate the error to the notebook.
        # (in case the user is not able to see the output from the Jupyter server)
        try:
            executable = self.get_executable()
        except Exception as e:
            return self.send_stderr(str(e))

        with tempfile.TemporaryFile("w+") as f:
            f.write(all_code)
            f.seek(0)
            got = subprocess.run(
                [executable, *args],
                stdin=f,
                stderr=subprocess.PIPE,
                stdout=subprocess.PIPE,
                universal_newlines=True,
            )

        if not silent:
            if got.stderr:
                return self.send_stderr(got.stderr)
            else:
                return self.send_stdout(got.stdout)
        else:
            return self.make_status()


if __name__ == "__main__":
    import doctest

    doctest.testmod(extraglobs={"k": TableGenKernel()})
