#!/usr/bin/env fuchsia-vendored-python
# Copyright 2021 The Fuchsia Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""
Suggests OWNERS for projects.

For each project in a given jiri manifest file or at a given path, do the
following:
1. Check if it has an OWNERS file up the path (or at the root path only when
   run with `--skip_root_owners_only`). If so, skip.
2. Find references to the project via `gn refs`. If none, skip.
3. Find immediate owners for all referrers. If none, for each referrer travel
   one directory up and continue the search. Ignore root owners.

Example usage:
$ fx set ...
$ scripts/owner/suggest_owners.py \
--jiri_manifest integration/third_party/flower --csv csv.out

$ scripts/owner/suggest_owners.py --path third_party/crashpad --csv csv.out

$ scripts/owner/suggest_owners.py --path third_party/* --csv csv.out

$ scripts/owner/suggest_owners.py --path third_party/* --all_refs --csv csv.out

$ scripts/owner/suggest_owners.py --path third_party/* --all_refs --generate_missing

$ scripts/owner/suggest_owners.py \
    --jiri_manifest integration/third_party/flower --generate_missing --dry_run

$ scripts/owner/suggest_owners.py \
    --jiri_manifest integration/third_party/flower --skip_root_owners_only
"""

import argparse
import os
import re
import subprocess
import sys
import xml.etree.ElementTree as ET

# Matches a valid email address, more or less.
EMAIL = re.compile("^[\w%+-]+@[\w.-]+\.[a-zA-Z]{2,}$")


def maybe_run(dry_run, *command, **kwargs):
    if not dry_run:
        return check_output(*command, **kwargs)
    print("Dry-run: ", command)


def check_output(*command, **kwargs):
    try:
        return subprocess.check_output(
            command, stderr=subprocess.STDOUT, encoding="utf8", **kwargs
        )
    except subprocess.CalledProcessError as e:
        print("Failed: " + " ".join(command), file=sys.stderr)
        print(e.output, file=sys.stderr)
        raise e


def get_project_paths(jiri_manifest_path):
    manifest = ET.parse(jiri_manifest_path)
    root = manifest.getroot()
    projects = root.find("projects")
    return [project.get("path") for project in projects.findall("project")]


def get_referencing_paths(*args):
    build_dir = check_output("fx", "get-build-dir").strip()
    try:
        refs_out = check_output("fx", "gn", "refs", build_dir, *args)
    except Exception as e:
        print(f"Failed to find refs to {args}", file=sys.stderr)
        print(e.output, file=sys.stderr)
        return []
    # Remove empty lines, turn labels to paths, unique, sort
    return sorted(
        {line[2:].partition(":")[0] for line in refs_out.splitlines() if line}
    )


def get_filenames(path):
    filenames = []
    for dirpath, dirnames, names in os.walk(path):
        for name in names:
            filepath = os.path.join(dirpath, name)
            filenames.append(filepath)
    return filenames


def get_owners(path):
    owners_path = os.path.join(path, "OWNERS")
    if not os.path.exists(owners_path):
        return set()
    owners = set()
    for line in open(owners_path):
        line = line.strip()
        if line.startswith("include "):
            owners.update(
                get_owners(
                    line[len("include /") : (len(line) - len("/OWNERS"))]
                )
            )
        elif line.startswith("per-file "):
            owners.update(
                line[len("per-file ") :].partition("=")[2].strip().split(",")
            )
        elif line.startswith("#"):
            continue
        else:
            owners.add(line)
    # Remove stuff that doesn't look like an email address
    return {owner for owner in owners if EMAIL.match(owner)}


def find_owners_file(path, recursive=True):
    # Look for the OWNERS file in the given path.
    owners_path = os.path.join(path, "OWNERS")
    if os.path.exists(owners_path):
        return owners_path
    if not recursive:
        return None
    # If not found, search one directory up.
    parent_path = os.path.dirname(path)
    if parent_path and parent_path != path:
        return find_owners_file(parent_path)
    return None


def generate_owners_file(project_path, refs, owners, dry_run):
    # Find and include the OWNERS files of all references.
    includes = set()
    for ref in refs:
        path = find_owners_file(ref)
        if path:
            includes.add("include /" + path + "\n")

    # Write the OWNERS file.
    owners_file = os.path.join(project_path, "OWNERS")
    content = "".join(sorted(includes))
    if dry_run:
        print(f"Dry run: generating {owners_file} with content:\n{content}")
    else:
        print(f"Generating {owners_file}...")
        file = open(owners_file, "w")
        file.write(content)
        file.close()

    # `git add` the OWNERS file.
    try:
        maybe_run(dry_run, "git", "add", "OWNERS", "-v", cwd=project_path)
    except Exception as e:
        print(f"Failed to `git add` OWNERS file.", file=sys.stderr)
        print(e.output, file=sys.stderr)
        os.remove(owners_path)
        return

    # Commit the OWNERS file.
    try:
        commit_message = """[owners] Add OWNERS file

Add as owners the owners of the code that calls into this dependency.

The OWNERS file and this commit are generated by
//scripts/owners/suggest_owners.py.

Bug: 102810
"""
        maybe_run(
            dry_run, "git", "commit", "-m", commit_message, cwd=project_path
        )
    except Exception as e:
        print(f"Failed to commit OWNERS file.", file=sys.stderr)
        print(e.output, file=sys.stderr)
        maybe_run("git", "restore", "--staged", "OWNERS", cwd=project_path)
        os.remove(generate_owners_file)
        return

    # Upload the CL for review.
    try:
        reviewers = ",".join(owners)
        if not dry_run:
            # Prompt for confirmation to continue.
            choice = input(
                f"Uploading {owners_file} for review and adding "
                f"{reviewers} as reviewers. Do you want to continue? [y/N] "
            )
            if not choice.lower()[:1] == "y":
                check_output("git", "checkout", "origin/main", cwd=project_path)
                return

        upload_out = maybe_run(
            dry_run,
            "jiri",
            "upload",
            "-remoteBranch=main",
            "-r=" + reviewers,
            cwd=project_path,
        )
        if upload_out:
            print(upload_out)
    except Exception as e:
        print(f"Failed to upload CL for review.", file=sys.stderr)
        print(e.output, file=sys.stderr)
        maybe_run("git", "checkout", "origin/main", cwd=project_path)


def main():
    parser = argparse.ArgumentParser(description="Suggests owners for projects")
    group = parser.add_mutually_exclusive_group(required=True)
    group.add_argument("--jiri_manifest", help="Input jiri manifest file")
    group.add_argument(
        "--path", nargs="+", help="Input project path, relative to fuchsia root"
    )
    parser.add_argument(
        "--all_refs",
        action="store_true",
        help="Search for references to all targets and all files in input projects",
    )
    parser.add_argument(
        "--csv", help="Output csv file", type=argparse.FileType("w")
    )
    parser.add_argument(
        "--generate_missing",
        action="store_true",
        help="Generates OWNERS files for projects missing owners and uploads them for review.",
    )
    parser.add_argument(
        "--dry_run",
        action="store_true",
        help="Used in conjunction with `--generate_missing` to print the generated OWNERS file "
        "and git/jiri commands instead of creating the file and running the commands.",
    )
    parser.add_argument(
        "--skip_root_owners_only",
        action="store_true",
        default=False,
        help="Skips project only if it has an OWNERS files at the root path, and "
        "not in parent directories.",
    )
    args = parser.parse_args()
    if args.dry_run and not args.generate_missing:
        parser.error(
            "--dry_run: not allowed without argument --generate_missing"
        )

    # Set working directory to //
    fuchsia_root = os.path.dirname(  # //
        os.path.dirname(  # scripts/
            os.path.dirname(os.path.abspath(__file__))  # owner/
        )
    )
    os.chdir(fuchsia_root)

    if args.jiri_manifest:
        project_paths = get_project_paths(args.jiri_manifest)
    else:
        project_paths = [
            project.strip("/")
            for project in args.path
            if os.path.isdir(project)
        ]

    for project_path in project_paths:
        # Skip if the project has OWNERS.
        if owners_file := find_owners_file(
            project_path, not args.skip_root_owners_only
        ):
            print(f"{project_path} has owners at {owners_file}, skipping.")
            continue

        # If the path ends in `/src`, use the path without the `/src` ending to
        # search for references and generate OWNERS file (if configured).
        if project_path.endswith("/src"):
            project_path = project_path[: -len("/src")]

        # Search for references to any of the project's targets if `--all_refs`
        # is set, or for the top-level targets otherwise.
        refs = get_referencing_paths(
            project_path + ("/*" if args.all_refs else ":*")
        )
        if not refs and args.all_refs:
            print(
                f"{project_path} has no target references, searching for all file references."
            )
            files = get_filenames(project_path)
            refs = get_referencing_paths(project_path, *files)
        if not refs:
            print(f"{project_path} has no references, skipping.")
            continue
        # Filter // and internal references (paths inside the project)
        refs = {ref for ref in refs if ref and not ref.startswith(project_path)}

        owners = set()
        while not owners and refs:
            for ref in refs:
                owners.update(get_owners(ref))
            if not owners:
                # Go one directory up, terminating before //
                refs = {os.path.dirname(ref) for ref in refs}
                refs = {
                    ref
                    for ref in refs
                    if ref and not ref.startswith(project_path)
                }
        if not owners:
            print(f"{project_path} not referenced by anything owned, skipping.")
            continue

        print()
        print(f"{project_path} suggested owners:")
        print("\n".join(sorted(owners)))
        print()
        print(f"This is based on incoming references from:")
        print("\n".join(sorted(refs)))
        print()
        if args.csv:
            args.csv.write(f"{project_path},{owners},{refs}\n")

        if args.generate_missing:
            generate_owners_file(project_path, refs, owners, args.dry_run)


if __name__ == "__main__":
    sys.exit(main())
