# Copyright 2021 The ChromiumOS Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""Runs cargo clippy across the given files, dumping diagnostics to a JSON file.

This script is intended specifically for use with Tricium (go/tricium).
"""

import json
import logging
import os
from pathlib import Path
import re
from typing import Any, Dict, Iterable, List, NamedTuple, Text

from chromite.lib import commandline
from chromite.lib import cros_build_lib


class Error(Exception):
    """Base error class for tricium-cargo-clippy."""


class CargoClippyPackagePathError(Error):
    """Raised when no Package Path is provided."""

    def __init__(self, source: Text) -> None:
        super().__init__(f"{source} does not start with a package path")
        self.source = source


class CargoClippyJSONError(Error):
    """Raised when cargo-clippy parsing jobs are not proper JSON."""

    def __init__(self, source: Text, line_num: int) -> None:
        super().__init__(f"{source}:{line_num}: is not valid JSON")
        self.source = source
        self.line_num = line_num


class CargoClippyReasonError(Error):
    """Raised when cargo-clippy parsing jobs don't provide a "reason" field."""

    def __init__(self, source: Text, line_num: int) -> None:
        super().__init__(f"{source}:{line_num}: is missing its reason")
        self.source = source
        self.line_num = line_num


class CargoClippyFieldError(Error):
    """Raised when cargo-clippy parsing jobs fail to determine a field."""

    def __init__(self, source: Text, line_num: int, field: Text) -> None:
        super().__init__(
            f"{source}:{line_num}: {field} could not be parsed from original"
            " json"
        )
        self.source = source
        self.line_num = line_num
        self.field = field


def resolve_path(file_path: Text) -> Text:
    return str(Path(file_path).resolve())


class CodeLocation(NamedTuple):
    """Holds the location a ClippyDiagnostic Finding."""

    file_path: Text
    line_start: int
    line_end: int
    column_start: int
    column_end: int

    def to_dict(self):
        return {**self._asdict(), "file_path": self.file_path}


class ClippyDiagnostic(NamedTuple):
    """Holds information about a compiler message from Clippy."""

    locations: Iterable["CodeLocation"]
    level: Text
    message: Text

    def as_json(self):
        return json.dumps(
            {
                **self._asdict(),
                "locations": [loc.to_dict() for loc in self.locations],
            }
        )


def parse_locations(
    orig_json: Dict[Text, Any], package_path: Text, git_repo: Text
) -> Iterable["CodeLocation"]:
    """The code locations associated with this diagnostic as an iter.

    The relevant code location can appear in either the messages[spans] field,
    which will be used if present, or else child messages each have their own
    locations specified.

    Args:
        orig_json: An iterable of clippy entries in original json.
        package_path: A resolved path to the rust package.
        git_repo: Base directory for git repo to strip out in diagnostics.

    Yields:
        A CodeLocation object associated with a relevant span.

    Raises:
        CargoClippyFieldError: Parsing failed to determine any code locations.
    """
    spans = orig_json.get("message", {}).get("spans", [])
    children = orig_json.get("message", {}).get("children", [])
    for child in children:
        spans = spans + child.get("spans", [])
    locations = set()
    for span in spans:
        file_path = os.path.join(package_path, span.get("file_name"))
        if git_repo and file_path.startswith(f"{git_repo}/"):
            file_path = file_path[len(git_repo) + 1 :]
        else:
            # Remove ebuild work directories from prefix
            # Such as: "**/<package>-9999/work/<package>-9999/"
            #      or: "**/<package>-0.24.52-r9/work/<package>-0.24.52/"
            file_path = re.sub(
                r"(.*/)?([^/]+)-[^/]+/work/[^/]+/+", "", file_path
            )
        location = CodeLocation(
            file_path=file_path,
            line_start=span.get("line_start"),
            line_end=span.get("line_end"),
            column_start=span.get("column_start"),
            column_end=span.get("column_end"),
        )
        if location not in locations:
            locations.add(location)
            yield location


def parse_level(src: Text, src_line: int, orig_json: Dict[Text, Any]) -> Text:
    """The level (error or warning) associated with this diagnostic.

    Args:
        src: Name of the file orig_json was found in.
        src_line: Line number where orig_json was found.
        orig_json: An iterable of clippy entries in original json.

    Returns:
        The level of the diagnostic as a string (either error or warning).

    Raises:
        CargoClippyFieldError: Parsing failed to determine the level.
    """
    level = orig_json.get("level")
    if not level:
        level = orig_json.get("message", {}).get("level")
    if not level:
        raise CargoClippyFieldError(src, src_line, "level")
    return level


def parse_message(src: Text, src_line: int, orig_json: Dict[Text, Any]) -> Text:
    """The formatted linter message for this diagnostic.

    Args:
        src: Name of the file orig_json was found in.
        src_line: Line number where orig_json was found.
        orig_json: An iterable of clippy entries in original json.

    Returns:
        The rendered message of the diagnostic.

    Raises:
        CargoClippyFieldError: Parsing failed to determine the message.
    """
    message = orig_json.get("message", {}).get("rendered")
    if message is None:
        raise CargoClippyFieldError(src, src_line, "message")
    return message


def parse_diagnostics(
    src: Text, orig_jsons: Iterable[Text], git_repo: Text
) -> ClippyDiagnostic:
    """Parses original JSON to find the fields of a Clippy Diagnostic.

    Args:
        src: Name of the file orig_json was found in.
        orig_jsons: An iterable of clippy entries in original json.
        git_repo: Base directory for git repo to strip out in diagnostics.

    Yields:
        A ClippyDiagnostic for orig_json.

    Raises:
        CargoClippyJSONError: if a diagnostic is not valid JSON.
        CargoClippyReasonError: if a diagnostic is missing a "reason" field.
        CargoClippyFieldError: if a field cannot be determined while parsing.
    """
    for src_line, orig_json in enumerate(orig_jsons):
        try:
            line_json = json.loads(orig_json)
        except json.decoder.JSONDecodeError:
            json_error = CargoClippyJSONError(src, src_line)
            logging.error(json_error)
            raise json_error

        # We pass the path to the package in a special JSON on the first line
        if src_line == 0:
            package_path = line_json.get("package_path")
            if not package_path:
                raise CargoClippyPackagePathError(src)
            package_path = resolve_path(package_path)
            continue

        # Clippy outputs several types of logs, as distinguished by the "reason"
        # field, but we only want to process "compiler-message" logs.
        reason = line_json.get("reason")
        if reason is None:
            reason_error = CargoClippyReasonError(src, src_line)
            logging.error(reason_error)
            raise reason_error
        if reason != "compiler-message":
            continue

        locations = parse_locations(line_json, package_path, git_repo)
        level = parse_level(src, src_line, line_json)
        message = parse_message(src, src_line, line_json)

        # TODO(ryanbeltran): Export suggested replacements
        yield ClippyDiagnostic(locations, level, message)


def parse_files(input_dir: Text, git_repo: Text) -> Iterable[ClippyDiagnostic]:
    """Gets all compiler-message lints from all the input files in input_dir.

    Args:
        input_dir: path to directory to scan for files
        git_repo: Base directory for git repo to strip out in diagnostics.

    Yields:
        Clippy Diagnostics objects found in files in the input directory
    """
    for root_path, _, file_names in os.walk(input_dir):
        for file_name in file_names:
            file_path = os.path.join(root_path, file_name)
            with open(file_path, encoding="utf-8") as clippy_file:
                yield from parse_diagnostics(file_path, clippy_file, git_repo)


def filter_diagnostics(
    diags: Iterable[ClippyDiagnostic],
) -> Iterable[ClippyDiagnostic]:
    """Filters diagnostics and validates schemas."""
    for diag in diags:
        # ignore redundant messages: "aborting due to previous error..."
        if "aborting due to previous error" in diag.message:
            continue
        # findings with no location are never useful
        if not diag.locations:
            continue
        yield diag


def get_arg_parser() -> commandline.ArgumentParser:
    """Creates an argument parser for this script."""
    parser = commandline.ArgumentParser(description=__doc__)
    parser.add_argument(
        "--output",
        required=True,
        type="str_path",
        help="File to write results to.",
    )
    parser.add_argument(
        "--clippy-json-dir",
        type="str_path",
        help="Directory where clippy outputs were previously written to.",
    )
    parser.add_argument(
        "--git-repo-path",
        type="str_path",
        default="",
        help="Base directory for git repo to strip out in diagnostics.",
    )
    return parser


def main(argv: List[str]) -> None:
    cros_build_lib.AssertInsideChroot()

    logging.basicConfig()

    parser = get_arg_parser()
    opts = parser.parse_args(argv)
    opts.Freeze()

    input_dir = resolve_path(opts.clippy_json_dir)
    output_path = resolve_path(opts.output)
    git_repo = opts.git_repo_path

    diagnostics = filter_diagnostics(parse_files(input_dir, git_repo))
    with open(output_path, "w", encoding="utf-8") as output_file:
        output_file.writelines(f"{diag}\n" for diag in diagnostics)
