#!/usr/bin/env python3
# Copyright 2022 The ChromiumOS Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""Linter for various DIR_METADATA files."""

from __future__ import division

import json
import logging
import os
from pathlib import Path
from typing import Generator, List, Optional


_HACK_VAR_TO_DISABLE_ISORT = "hack"
# pylint: disable=wrong-import-position
import chromite_init  # pylint: disable=unused-import

from chromite.lib import commandline
from chromite.lib import constants
from chromite.lib import cros_build_lib
from chromite.lib import git


TOP_DIR = Path(__file__).resolve().parent.parent


def GetActiveProjects() -> Generator[Path, None, None]:
    """Return the list of active projects."""
    # Look at all the paths (files & dirs) in the top of the git repo.  This way
    # we ignore local directories devs created that aren't actually committed.
    cmd = ["ls-tree", "--name-only", "-z", "HEAD"]
    result = git.RunGit(TOP_DIR, cmd)

    # Split the output on NULs to avoid whitespace/etc... issues.
    paths = result.stdout.split("\0")

    # ls-tree -z will include a trailing NUL on all entries, not just
    # separation, so filter it out if found (in case ls-tree behavior changes on
    # us).
    for path in [Path(x) for x in paths if x]:
        if (TOP_DIR / path).is_dir():
            yield path


# Legacy projects that don't have a DIR_METADATA file.
# Someone should claim them :D.
LEGACYLIST = {
    "avtest_label_detect",
    "bootstat",
    "cecservice",
    "cfm-dfu-notification",
    "chromeos-common-script",
    "chromeos-dbus-bindings",
    "chromeos-nvt-tcon-updater",
    "codelab",
    "crosdns",
    "croslog",
    "disk_updater",
    "dlp",
    "easy-unlock",
    "glib-bridge",
    "goldfishd",
    "hardware_verifier",
    "image-burner",
    "imageloader",
    "installer",
    "libbrillo",
    "libchromeos-rs",
    "libchromeos-ui",
    "libcontainer",
    "libpasswordprovider",
    "media_capabilities",
    "midis",
    "minios",
    "mist",
    "ml_benchmark",
    "modem-utilities",
    "nnapi",
    "oobe_config",
    "p2p",
    "pciguard",
    "perfetto_simple_producer",
    "permission_broker",
    "policy_proto",
    "policy_utils",
    "power_manager",
    "regions",
    "resourced",
    "run_oci",
    "runtime_probe",  # TODO(b/262377381)
    "screen-capture-utils",
    "secanomalyd",
    "sepolicy",
    "st_flash",
    "syslog-cat",
    "system-proxy",
    "timberslide",
    "touch_firmware_calibration",
    "ureadahead-diff",
    "usb_bouncer",
    "verity",
    "virtual_file_provider",
}

# Mapping between tracker & component key name.
DIR_MD_COMPONENT_KEY = (
    ("buganizer", "componentId"),
    ("buganizer_public", "componentId"),
    ("monorail", "component"),
)


def CheckSubdirs() -> int:
    """Check the subdir DIR_METADATA files exist.

    Returns:
        0 if no issues are found, 1 otherwise.
    """

    ret = 0
    for proj in GetActiveProjects():
        path = TOP_DIR / proj / "DIR_METADATA"
        if path.exists():
            if str(proj) in LEGACYLIST:
                logging.error(
                    '*** Project "%s" is in no-DIR_METADATA LEGACYLIST, but '
                    "actually has one. Please remove it from %s:LEGACYLIST!",
                    proj,
                    __file__,
                )
                ret = 1
        else:
            if str(proj) not in LEGACYLIST:
                logging.error(
                    '*** Project "%s" needs a DIR_METADATA file; see common-mk/'
                    "DIR_METADATA for an example",
                    proj,
                )
                ret = 1
            continue

        data = path.read_text()
        for i, line in enumerate(data.splitlines(), start=1):
            if line.rstrip() != line:
                logging.error("*** %s:%i: Trim trailing whitespace", path, i)
                ret = 1

        if not data:
            logging.error("*** %s: File is empty", path)
            ret = 1

        if not data.endswith("\n"):
            logging.error("*** %s: Missing trailing newline", path)
            ret = 1

        if data.startswith("\n"):
            logging.error("*** %s: Trim leading blanklines", path)
            ret = 1

        if data.endswith("\n\n"):
            logging.error("*** %s: Trim trailing blanklines", path)
            ret = 1

    # Make sure the projects have declared how to route bugs.
    result = cros_build_lib.dbg_run(
        [
            os.path.join(constants.DEPOT_TOOLS_DIR, "dirmd"),
            "read",
            "-form",
            "computed",
        ],
        cwd=TOP_DIR,
        capture_output=True,
        check=True,
    )
    dirmd = json.loads(result.stdout)
    for project, data in dirmd["dirs"].items():
        bug_component_found = False
        for tracker, key in DIR_MD_COMPONENT_KEY:
            if tracker in data:
                if key not in data[tracker]:
                    logging.error(
                        '*** %s: Missing tracker "%s" component "%s"',
                        project,
                        tracker,
                        key,
                    )
                else:
                    bug_component_found = True
        if not bug_component_found:
            logging.error("*** %s: Missing bug component information", project)

    # Make sure the list doesn't get stale itself.
    old_projects = LEGACYLIST - set(x.name for x in GetActiveProjects())
    if old_projects:
        logging.error(
            "*** %s:LEGACYLIST contains old entries %s.  Please remove them.",
            __file__,
            old_projects,
        )
        ret = 1

    return ret


def GetParser() -> commandline.ArgumentParser:
    """Return an argument parser."""
    parser = commandline.ArgumentParser(description=__doc__)
    return parser


def main(argv: List[str]) -> Optional[int]:
    """The main func!"""
    parser = GetParser()
    opts = parser.parse_args(argv)
    opts.Freeze()

    return CheckSubdirs()


if __name__ == "__main__":
    commandline.ScriptWrapperMain(lambda _: main)
