# Copyright (C) 2008 The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

import os
import re
import sys
import traceback
import urllib.parse

from error import HookError
from git_refs import HEAD


# The API we've documented to hook authors.  Keep in sync with repo-hooks.md.
_API_ARGS = {
    "pre-upload": {"project_list", "worktree_list"},
    "post-sync": {"repo_topdir"},
}


class RepoHook:
    """A RepoHook contains information about a script to run as a hook.

    Hooks are used to run a python script before running an upload (for
    instance, to run presubmit checks).  Eventually, we may have hooks for other
    actions.

    This shouldn't be confused with files in the 'repo/hooks' directory.  Those
    files are copied into each '.git/hooks' folder for each project.  Repo-level
    hooks are associated instead with repo actions.

    Hooks are always python.  When a hook is run, we will load the hook into the
    interpreter and execute its main() function.

    Combinations of hook option flags:
    - no-verify=False, verify=False (DEFAULT):
      If stdout is a tty, can prompt about running hooks if needed.
      If user denies running hooks, the action is cancelled. If stdout is
      not a tty and we would need to prompt about hooks, action is
      cancelled.
    - no-verify=False, verify=True:
      Always run hooks with no prompt.
    - no-verify=True, verify=False:
      Never run hooks, but run action anyway (AKA bypass hooks).
    - no-verify=True, verify=True:
      Invalid
    """

    def __init__(
        self,
        hook_type,
        hooks_project,
        repo_topdir,
        manifest_url,
        bug_url=None,
        bypass_hooks=False,
        allow_all_hooks=False,
        ignore_hooks=False,
        abort_if_user_denies=False,
    ):
        """RepoHook constructor.

        Params:
            hook_type: A string representing the type of hook. This is also used
                to figure out the name of the file containing the hook. For
                example: 'pre-upload'.
            hooks_project: The project containing the repo hooks.
                If you have a manifest, this is manifest.repo_hooks_project.
                OK if this is None, which will make the hook a no-op.
            repo_topdir: The top directory of the repo client checkout.
                This is the one containing the .repo directory. Scripts will
                run with CWD as this directory.
                If you have a manifest, this is manifest.topdir.
            manifest_url: The URL to the manifest git repo.
            bug_url: The URL to report issues.
            bypass_hooks: If True, then 'Do not run the hook'.
            allow_all_hooks: If True, then 'Run the hook without prompting'.
            ignore_hooks: If True, then 'Do not abort action if hooks fail'.
            abort_if_user_denies: If True, we'll abort running the hook if the
                user doesn't allow us to run the hook.
        """
        self._hook_type = hook_type
        self._hooks_project = hooks_project
        self._repo_topdir = repo_topdir
        self._manifest_url = manifest_url
        self._bug_url = bug_url
        self._bypass_hooks = bypass_hooks
        self._allow_all_hooks = allow_all_hooks
        self._ignore_hooks = ignore_hooks
        self._abort_if_user_denies = abort_if_user_denies

        # Store the full path to the script for convenience.
        self._script_fullpath = None
        if self._hooks_project and self._hooks_project.worktree:
            self._script_fullpath = os.path.join(
                self._hooks_project.worktree, self._hook_type + ".py"
            )

    def _GetHash(self):
        """Return a hash of the contents of the hooks directory.

        We'll just use git to do this.  This hash has the property that if
        anything changes in the directory we will return a different has.

        SECURITY CONSIDERATION:
            This hash only represents the contents of files in the hook
            directory, not any other files imported or called by hooks.  Changes
            to imported files can change the script behavior without affecting
            the hash.

        Returns:
            A string representing the hash.  This will always be ASCII so that
            it can be printed to the user easily.
        """
        assert self._hooks_project, "Must have hooks to calculate their hash."

        # We will use the work_git object rather than just calling
        # GetRevisionId(). That gives us a hash of the latest checked in version
        # of the files that the user will actually be executing.  Specifically,
        # GetRevisionId() doesn't appear to change even if a user checks out a
        # different version of the hooks repo (via git checkout) nor if a user
        # commits their own revs.
        #
        # NOTE: Local (non-committed) changes will not be factored into this
        # hash. I think this is OK, since we're really only worried about
        # warning the user about upstream changes.
        return self._hooks_project.work_git.rev_parse(HEAD)

    def _GetMustVerb(self):
        """Return 'must' if the hook is required; 'should' if not."""
        if self._abort_if_user_denies:
            return "must"
        else:
            return "should"

    def _CheckForHookApproval(self):
        """Check to see whether this hook has been approved.

        We'll accept approval of manifest URLs if they're using secure
        transports. This way the user can say they trust the manifest hoster.
        For insecure hosts, we fall back to checking the hash of the hooks repo.

        Note that we ask permission for each individual hook even though we use
        the hash of all hooks when detecting changes.  We'd like the user to be
        able to approve / deny each hook individually.  We only use the hash of
        all hooks because there is no other easy way to detect changes to local
        imports.

        Returns:
            True if this hook is approved to run; False otherwise.

        Raises:
            HookError: Raised if the user doesn't approve and
                abort_if_user_denies was passed to the consturctor.
        """
        if self._ManifestUrlHasSecureScheme():
            return self._CheckForHookApprovalManifest()
        else:
            return self._CheckForHookApprovalHash()

    def _CheckForHookApprovalHelper(
        self, subkey, new_val, main_prompt, changed_prompt
    ):
        """Check for approval for a particular attribute and hook.

        Args:
            subkey: The git config key under [repo.hooks.<hook_type>] to store
                the last approved string.
            new_val: The new value to compare against the last approved one.
            main_prompt: Message to display to the user to ask for approval.
            changed_prompt: Message explaining why we're re-asking for approval.

        Returns:
            True if this hook is approved to run; False otherwise.

        Raises:
            HookError: Raised if the user doesn't approve and
                abort_if_user_denies was passed to the consturctor.
        """
        hooks_config = self._hooks_project.config
        git_approval_key = f"repo.hooks.{self._hook_type}.{subkey}"

        # Get the last value that the user approved for this hook; may be None.
        old_val = hooks_config.GetString(git_approval_key)

        if old_val is not None:
            # User previously approved hook and asked not to be prompted again.
            if new_val == old_val:
                # Approval matched.  We're done.
                return True
            else:
                # Give the user a reason why we're prompting, since they last
                # told us to "never ask again".
                prompt = f"WARNING: {changed_prompt}\n\n"
        else:
            prompt = ""

        # Prompt the user if we're not on a tty; on a tty we'll assume "no".
        if sys.stdout.isatty():
            prompt += main_prompt + " (yes/always/NO)? "
            response = input(prompt).lower()
            print()

            # User is doing a one-time approval.
            if response in ("y", "yes"):
                return True
            elif response == "always":
                hooks_config.SetString(git_approval_key, new_val)
                return True

        # For anything else, we'll assume no approval.
        if self._abort_if_user_denies:
            raise HookError(
                "You must allow the %s hook or use --no-verify."
                % self._hook_type
            )

        return False

    def _ManifestUrlHasSecureScheme(self):
        """Check if the URI for the manifest is a secure transport."""
        secure_schemes = (
            "file",
            "https",
            "ssh",
            "persistent-https",
            "sso",
            "rpc",
        )
        parse_results = urllib.parse.urlparse(self._manifest_url)
        return parse_results.scheme in secure_schemes

    def _CheckForHookApprovalManifest(self):
        """Check whether the user has approved this manifest host.

        Returns:
            True if this hook is approved to run; False otherwise.
        """
        return self._CheckForHookApprovalHelper(
            "approvedmanifest",
            self._manifest_url,
            f"Run hook scripts from {self._manifest_url}",
            f"Manifest URL has changed since {self._hook_type} was allowed.",
        )

    def _CheckForHookApprovalHash(self):
        """Check whether the user has approved the hooks repo.

        Returns:
            True if this hook is approved to run; False otherwise.
        """
        prompt = (
            "Repo %s run the script:\n"
            "  %s\n"
            "\n"
            "Do you want to allow this script to run"
        )
        return self._CheckForHookApprovalHelper(
            "approvedhash",
            self._GetHash(),
            prompt % (self._GetMustVerb(), self._script_fullpath),
            f"Scripts have changed since {self._hook_type} was allowed.",
        )

    @staticmethod
    def _ExtractInterpFromShebang(data):
        """Extract the interpreter used in the shebang.

        Try to locate the interpreter the script is using (ignoring `env`).

        Args:
            data: The file content of the script.

        Returns:
            The basename of the main script interpreter, or None if a shebang is
            not used or could not be parsed out.
        """
        firstline = data.splitlines()[:1]
        if not firstline:
            return None

        # The format here can be tricky.
        shebang = firstline[0].strip()
        m = re.match(r"^#!\s*([^\s]+)(?:\s+([^\s]+))?", shebang)
        if not m:
            return None

        # If the using `env`, find the target program.
        interp = m.group(1)
        if os.path.basename(interp) == "env":
            interp = m.group(2)

        return interp

    def _ExecuteHookViaImport(self, data, context, **kwargs):
        """Execute the hook code in |data| directly.

        Args:
            data: The code of the hook to execute.
            context: Basic Python context to execute the hook inside.
            kwargs: Arbitrary arguments to pass to the hook script.

        Raises:
            HookError: When the hooks failed for any reason.
        """
        # Exec, storing global context in the context dict.  We catch exceptions
        # and convert to a HookError w/ just the failing traceback.
        try:
            exec(compile(data, self._script_fullpath, "exec"), context)
        except Exception:
            raise HookError(
                "%s\nFailed to import %s hook; see traceback above."
                % (traceback.format_exc(), self._hook_type)
            )

        # Running the script should have defined a main() function.
        if "main" not in context:
            raise HookError('Missing main() in: "%s"' % self._script_fullpath)

        # Call the main function in the hook.  If the hook should cause the
        # build to fail, it will raise an Exception.  We'll catch that convert
        # to a HookError w/ just the failing traceback.
        try:
            context["main"](**kwargs)
        except Exception:
            raise HookError(
                "%s\nFailed to run main() for %s hook; see traceback "
                "above." % (traceback.format_exc(), self._hook_type)
            )

    def _ExecuteHook(self, **kwargs):
        """Actually execute the given hook.

        This will run the hook's 'main' function in our python interpreter.

        Args:
            kwargs: Keyword arguments to pass to the hook.  These are often
                specific to the hook type.  For instance, pre-upload hooks will
                contain a project_list.
        """
        # Keep sys.path and CWD stashed away so that we can always restore them
        # upon function exit.
        orig_path = os.getcwd()
        orig_syspath = sys.path

        try:
            # Always run hooks with CWD as topdir.
            os.chdir(self._repo_topdir)

            # Put the hook dir as the first item of sys.path so hooks can do
            # relative imports.  We want to replace the repo dir as [0] so
            # hooks can't import repo files.
            sys.path = [os.path.dirname(self._script_fullpath)] + sys.path[1:]

            # Initial global context for the hook to run within.
            context = {"__file__": self._script_fullpath}

            # Add 'hook_should_take_kwargs' to the arguments to be passed to
            # main. We don't actually want hooks to define their main with this
            # argument--it's there to remind them that their hook should always
            # take **kwargs.
            # For instance, a pre-upload hook should be defined like:
            #   def main(project_list, **kwargs):
            #
            # This allows us to later expand the API without breaking old hooks.
            kwargs = kwargs.copy()
            kwargs["hook_should_take_kwargs"] = True

            # See what version of python the hook has been written against.
            data = open(self._script_fullpath).read()
            interp = self._ExtractInterpFromShebang(data)
            if interp:
                prog = os.path.basename(interp)
                if prog.startswith("python2"):
                    raise HookError("Python 2 is not supported")

            # Run the hook by importing directly.
            self._ExecuteHookViaImport(data, context, **kwargs)
        finally:
            # Restore sys.path and CWD.
            sys.path = orig_syspath
            os.chdir(orig_path)

    def _CheckHook(self):
        # Bail with a nice error if we can't find the hook.
        if not os.path.isfile(self._script_fullpath):
            raise HookError(
                "Couldn't find repo hook: %s" % self._script_fullpath
            )

    def Run(self, **kwargs):
        """Run the hook.

        If the hook doesn't exist (because there is no hooks project or because
        this particular hook is not enabled), this is a no-op.

        Args:
            user_allows_all_hooks: If True, we will never prompt about running
                the hook--we'll just assume it's OK to run it.
            kwargs: Keyword arguments to pass to the hook.  These are often
                specific to the hook type.  For instance, pre-upload hooks will
                contain a project_list.

        Returns:
            True: On success or ignore hooks by user-request
            False: The hook failed. The caller should respond with aborting the
                action. Some examples in which False is returned:
                * Finding the hook failed while it was enabled, or
                * the user declined to run a required hook (from
                    _CheckForHookApproval)
                In all these cases the user did not pass the proper arguments to
                ignore the result through the option combinations as listed in
                AddHookOptionGroup().
        """
        # Make sure our own callers use the documented API.
        exp_kwargs = _API_ARGS.get(self._hook_type, set())
        got_kwargs = set(kwargs.keys())
        if exp_kwargs != got_kwargs:
            print(
                "repo internal error: "
                f"hook '{self._hook_type}' called incorrectly\n"
                f"  got:      {sorted(got_kwargs)}\n"
                f"  expected: {sorted(exp_kwargs)}\n"
                f"Please file a bug: {self._bug_url}",
                file=sys.stderr,
            )
            return False

        # Do not do anything in case bypass_hooks is set, or
        # no-op if there is no hooks project or if hook is disabled.
        if (
            self._bypass_hooks
            or not self._hooks_project
            or not self._script_fullpath
            or self._hook_type not in self._hooks_project.enabled_repo_hooks
        ):
            return True

        passed = True
        try:
            self._CheckHook()

            # Make sure the user is OK with running the hook.
            if self._allow_all_hooks or self._CheckForHookApproval():
                # Run the hook with the same version of python we're using.
                self._ExecuteHook(**kwargs)
        except SystemExit as e:
            passed = False
            print(
                "ERROR: %s hooks exited with exit code: %s"
                % (self._hook_type, str(e)),
                file=sys.stderr,
            )
        except HookError as e:
            passed = False
            print("ERROR: %s" % str(e), file=sys.stderr)

        if not passed and self._ignore_hooks:
            print(
                "\nWARNING: %s hooks failed, but continuing anyways."
                % self._hook_type,
                file=sys.stderr,
            )
            passed = True

        return passed

    @classmethod
    def FromSubcmd(cls, manifest, opt, *args, **kwargs):
        """Method to construct the repo hook class

        Args:
            manifest: The current active manifest for this command from which we
                extract a couple of fields.
            opt: Contains the commandline options for the action of this hook.
                It should contain the options added by AddHookOptionGroup() in
                which we are interested in RepoHook execution.
        """
        for key in ("bypass_hooks", "allow_all_hooks", "ignore_hooks"):
            kwargs.setdefault(key, getattr(opt, key))
        kwargs.update(
            {
                "hooks_project": manifest.repo_hooks_project,
                "repo_topdir": manifest.topdir,
                "manifest_url": manifest.manifestProject.GetRemote(
                    "origin"
                ).url,
                "bug_url": manifest.contactinfo.bugurl,
            }
        )
        return cls(*args, **kwargs)

    @staticmethod
    def AddOptionGroup(parser, name):
        """Help options relating to the various hooks."""

        # Note that verify and no-verify are NOT opposites of each other, which
        # is why they store to different locations. We are using them to match
        # 'git commit' syntax.
        group = parser.add_option_group(name + " hooks")
        group.add_option(
            "--no-verify",
            dest="bypass_hooks",
            action="store_true",
            help="Do not run the %s hook." % name,
        )
        group.add_option(
            "--verify",
            dest="allow_all_hooks",
            action="store_true",
            help="Run the %s hook without prompting." % name,
        )
        group.add_option(
            "--ignore-hooks",
            action="store_true",
            help="Do not abort if %s hooks fail." % name,
        )
