# Copyright (C) 2009 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 functools
import sys
from typing import NamedTuple

from color import Coloring
from command import DEFAULT_LOCAL_JOBS
from command import PagedCommand
from error import GitError
from error import InvalidArgumentsError
from error import SilentRepoExitError
from git_command import GitCommand
from repo_logging import RepoLogger


logger = RepoLogger(__file__)


class GrepColoring(Coloring):
    def __init__(self, config):
        Coloring.__init__(self, config, "grep")
        self.project = self.printer("project", attr="bold")
        self.fail = self.printer("fail", fg="red")


class ExecuteOneResult(NamedTuple):
    """Result from an execute instance."""

    project_idx: int
    rc: int
    stdout: str
    stderr: str
    error: GitError


class GrepCommandError(SilentRepoExitError):
    """Grep command failure. Since Grep command
    output already outputs errors ensure that
    aggregate errors exit silently."""


class Grep(PagedCommand):
    COMMON = True
    helpSummary = "Print lines matching a pattern"
    helpUsage = """
%prog {pattern | -e pattern} [<project>...]
"""
    helpDescription = """
Search for the specified patterns in all project files.

# Boolean Options

The following options can appear as often as necessary to express
the pattern to locate:

 -e PATTERN
 --and, --or, --not, -(, -)

Further, the -r/--revision option may be specified multiple times
in order to scan multiple trees.  If the same file matches in more
than one tree, only the first result is reported, prefixed by the
revision name it was found under.

# Examples

Look for a line that has '#define' and either 'MAX_PATH or 'PATH_MAX':

  repo grep -e '#define' --and -\\( -e MAX_PATH -e PATH_MAX \\)

Look for a line that has 'NODE' or 'Unexpected' in files that
contain a line that matches both expressions:

  repo grep --all-match -e NODE -e Unexpected

"""
    PARALLEL_JOBS = DEFAULT_LOCAL_JOBS

    @staticmethod
    def _carry_option(_option, opt_str, value, parser):
        pt = getattr(parser.values, "cmd_argv", None)
        if pt is None:
            pt = []
            setattr(parser.values, "cmd_argv", pt)

        if opt_str == "-(":
            pt.append("(")
        elif opt_str == "-)":
            pt.append(")")
        else:
            pt.append(opt_str)

        if value is not None:
            pt.append(value)

    def _CommonOptions(self, p):
        """Override common options slightly."""
        super()._CommonOptions(p, opt_v=False)

    def _Options(self, p):
        g = p.add_option_group("Sources")
        g.add_option(
            "--cached",
            action="callback",
            callback=self._carry_option,
            help="Search the index, instead of the work tree",
        )
        g.add_option(
            "-r",
            "--revision",
            dest="revision",
            action="append",
            metavar="TREEish",
            help="Search TREEish, instead of the work tree",
        )

        g = p.add_option_group("Pattern")
        g.add_option(
            "-e",
            action="callback",
            callback=self._carry_option,
            metavar="PATTERN",
            type="str",
            help="Pattern to search for",
        )
        g.add_option(
            "-i",
            "--ignore-case",
            action="callback",
            callback=self._carry_option,
            help="Ignore case differences",
        )
        g.add_option(
            "-a",
            "--text",
            action="callback",
            callback=self._carry_option,
            help="Process binary files as if they were text",
        )
        g.add_option(
            "-I",
            action="callback",
            callback=self._carry_option,
            help="Don't match the pattern in binary files",
        )
        g.add_option(
            "-w",
            "--word-regexp",
            action="callback",
            callback=self._carry_option,
            help="Match the pattern only at word boundaries",
        )
        g.add_option(
            "-v",
            "--invert-match",
            action="callback",
            callback=self._carry_option,
            help="Select non-matching lines",
        )
        g.add_option(
            "-G",
            "--basic-regexp",
            action="callback",
            callback=self._carry_option,
            help="Use POSIX basic regexp for patterns (default)",
        )
        g.add_option(
            "-E",
            "--extended-regexp",
            action="callback",
            callback=self._carry_option,
            help="Use POSIX extended regexp for patterns",
        )
        g.add_option(
            "-F",
            "--fixed-strings",
            action="callback",
            callback=self._carry_option,
            help="Use fixed strings (not regexp) for pattern",
        )

        g = p.add_option_group("Pattern Grouping")
        g.add_option(
            "--all-match",
            action="callback",
            callback=self._carry_option,
            help="Limit match to lines that have all patterns",
        )
        g.add_option(
            "--and",
            "--or",
            "--not",
            action="callback",
            callback=self._carry_option,
            help="Boolean operators to combine patterns",
        )
        g.add_option(
            "-(",
            "-)",
            action="callback",
            callback=self._carry_option,
            help="Boolean operator grouping",
        )

        g = p.add_option_group("Output")
        g.add_option(
            "-n",
            action="callback",
            callback=self._carry_option,
            help="Prefix the line number to matching lines",
        )
        g.add_option(
            "-C",
            action="callback",
            callback=self._carry_option,
            metavar="CONTEXT",
            type="str",
            help="Show CONTEXT lines around match",
        )
        g.add_option(
            "-B",
            action="callback",
            callback=self._carry_option,
            metavar="CONTEXT",
            type="str",
            help="Show CONTEXT lines before match",
        )
        g.add_option(
            "-A",
            action="callback",
            callback=self._carry_option,
            metavar="CONTEXT",
            type="str",
            help="Show CONTEXT lines after match",
        )
        g.add_option(
            "-l",
            "--name-only",
            "--files-with-matches",
            action="callback",
            callback=self._carry_option,
            help="Show only file names containing matching lines",
        )
        g.add_option(
            "-L",
            "--files-without-match",
            action="callback",
            callback=self._carry_option,
            help="Show only file names not containing matching lines",
        )

    @classmethod
    def _ExecuteOne(cls, cmd_argv, project_idx):
        """Process one project."""
        project = cls.get_parallel_context()["projects"][project_idx]
        try:
            p = GitCommand(
                project,
                cmd_argv,
                bare=False,
                capture_stdout=True,
                capture_stderr=True,
                verify_command=True,
            )
        except GitError as e:
            return ExecuteOneResult(project_idx, -1, None, str(e), e)

        try:
            error = None
            rc = p.Wait()
        except GitError as e:
            rc = 1
            error = e
        return ExecuteOneResult(project_idx, rc, p.stdout, p.stderr, error)

    @staticmethod
    def _ProcessResults(
        full_name, have_rev, opt, projects, _pool, out, results
    ):
        git_failed = False
        bad_rev = False
        have_match = False
        _RelPath = lambda p: p.RelPath(local=opt.this_manifest_only)
        errors = []

        for result in results:
            project = projects[result.project_idx]
            if result.rc < 0:
                git_failed = True
                out.project("--- project %s ---" % _RelPath(project))
                out.nl()
                out.fail("%s", result.stderr)
                out.nl()
                errors.append(result.error)
                continue

            if result.rc:
                # no results
                if result.stderr:
                    if (
                        have_rev
                        and "fatal: ambiguous argument" in result.stderr
                    ):
                        bad_rev = True
                    else:
                        out.project("--- project %s ---" % _RelPath(project))
                        out.nl()
                        out.fail("%s", result.stderr.strip())
                        out.nl()
                    if result.error is not None:
                        errors.append(result.error)
                continue
            have_match = True

            # We cut the last element, to avoid a blank line.
            r = result.stdout.split("\n")
            r = r[0:-1]

            if have_rev and full_name:
                for line in r:
                    rev, line = line.split(":", 1)
                    out.write("%s", rev)
                    out.write(":")
                    out.project(_RelPath(project))
                    out.write("/")
                    out.write("%s", line)
                    out.nl()
            elif full_name:
                for line in r:
                    out.project(_RelPath(project))
                    out.write("/")
                    out.write("%s", line)
                    out.nl()
            else:
                for line in r:
                    print(line)

        return (git_failed, bad_rev, have_match, errors)

    def Execute(self, opt, args):
        out = GrepColoring(self.manifest.manifestProject.config)

        cmd_argv = ["grep"]
        if out.is_on:
            cmd_argv.append("--color")
        cmd_argv.extend(getattr(opt, "cmd_argv", []))

        if "-e" not in cmd_argv:
            if not args:
                self.Usage()
            cmd_argv.append("-e")
            cmd_argv.append(args[0])
            args = args[1:]

        projects = self.GetProjects(
            args, all_manifests=not opt.this_manifest_only
        )

        full_name = False
        if len(projects) > 1:
            cmd_argv.append("--full-name")
            full_name = True

        have_rev = False
        if opt.revision:
            if "--cached" in cmd_argv:
                msg = "fatal: cannot combine --cached and --revision"
                logger.error(msg)
                raise InvalidArgumentsError(msg)
            have_rev = True
            cmd_argv.extend(opt.revision)
        cmd_argv.append("--")

        with self.ParallelContext():
            self.get_parallel_context()["projects"] = projects
            git_failed, bad_rev, have_match, errors = self.ExecuteInParallel(
                opt.jobs,
                functools.partial(self._ExecuteOne, cmd_argv),
                range(len(projects)),
                callback=functools.partial(
                    self._ProcessResults, full_name, have_rev, opt, projects
                ),
                output=out,
                ordered=True,
                chunksize=1,
            )

        if git_failed:
            raise GrepCommandError(
                "error: git failures", aggregate_errors=errors
            )
        elif have_match:
            sys.exit(0)
        elif have_rev and bad_rev:
            for r in opt.revision:
                logger.error("error: can't search revision %s", r)
        raise GrepCommandError(aggregate_errors=errors)
