#!/usr/bin/env fuchsia-vendored-python
# Copyright 2024 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.
"""
Attempts to replace all instances of the `NEXT` pseudo-API-level with a
concrete value.

This is done heuristically, based on text. Always do a subsequent codebase-wide
regular expression search for `\bNEXT\b` after running this script, and ensure
it got everything. If you find any coverage gaps, please amend this script to
fix them.

Usage:

    ./scripts/versioning/replace_next.py --fuchsia-dir $PWD --new-api-level 24
"""
import argparse
import concurrent.futures
import dataclasses
import pathlib
import re
import subprocess
from typing import Generator

IGNORED_RELATIVE_PATHS: set[pathlib.Path] = {
    pathlib.Path("tools/fidl/fidlc/testdata/versions.test.fidl"),
    pathlib.Path("zircon/system/availability_test.c"),
    pathlib.Path("tools/fidl/fidlc/tests/versioning_attribute_tests.cc"),
}


@dataclasses.dataclass
class Pattern:
    # `sub_regex` will only be applied to files whose path (relative to
    # FUCHSIA_DIR) matches this regex.
    path_regex: re.Pattern[str]

    # Substitution to apply to the file. Must have a capture group named
    # "prefix" and another named "suffix". Any matches will be replaced with
    # <prefix>new_api_level<suffix>.
    sub_regex: re.Pattern[str]

    def path_matches(self, rel_path: pathlib.Path) -> bool:
        """Returns true if this pattern should apply to the given file."""
        return bool(self.path_regex.search(str(rel_path)))

    def substitute(self, text: str, new_api_level: str) -> str:
        """Performs the substitution and returns the result."""

        def sub_fn(m: re.Match[str]) -> str:
            return m.group("prefix") + new_api_level + m.group("suffix")

        return self.sub_regex.sub(sub_fn, text)


# `json` is included because magma.json is used to generate a header and thus can
# contain the macros.
CPP_PATH_REGEX: re.Pattern[str] = re.compile(r"\.(h|c|cc|json)$")


PATTERNS = [
    Pattern(
        path_regex=CPP_PATH_REGEX,
        # Matches macros like `FUCHSIA_API_LEVEL_AT_LEAST(NEXT)`, at the end of
        # lines.
        #
        # Possible coverage gaps:
        # - FUCHSIA_API_LEVEL_AT_LEAST(NEXT) && FUCHSIA_API_LEVEL_LESS_THAN(HEAD)
        # - FUCHSIA_API_LEVEL_AT_LEAST( NEXT )
        sub_regex=re.compile(r"(?P<prefix>\()NEXT(?P<suffix>\)(\n|$))"),
    ),
    Pattern(
        path_regex=CPP_PATH_REGEX,
        # Matches annotations like `ZX_AVAILABLE_SINCE(NEXT)` or
        # `ZX_REMOVED_SINCE(1, 19,
        #                   NEXT,
        #                   "Use DoNewThing() instead")`
        #
        # Possible coverage gaps:
        # - ZX_REMOVED_SINCE((1), 19, NEXT)
        sub_regex=re.compile(
            r"(?P<prefix>_SINCE\([^)]*)NEXT(?P<suffix>)", re.MULTILINE
        ),
    ),
    Pattern(
        path_regex=re.compile(r"\.rs$"),
        # Matches `cfg` predicates like `fuchsia_api_level_at_least = "NEXT"`.
        # Possible coverage gaps:
        # - Multiple instances on the same line?
        sub_regex=re.compile(
            r"(?P<prefix>fuchsia_api_level_.*\")NEXT(?P<suffix>\")",
            re.MULTILINE,
        ),
    ),
    Pattern(
        path_regex=re.compile(r"\.fidl$"),
        # Matches annotations like `@available(added=NEXT)` or
        # `@available(added=15, deprecated=22, removed=NEXT)`.
        #
        # Possible coverage gaps:
        # - The exclusion of `[^_;(A-Z]` is somewhat arbitrary.
        sub_regex=re.compile(
            r"(?P<prefix>= *)NEXT(?P<suffix>[^_;(A-Z])", re.MULTILINE
        ),
    ),
]


def get_git_files_for_substitution(
    fuchsia_dir: pathlib.Path,
) -> Generator[pathlib.Path, None, None]:
    """Calls `git ls-files` in the given directory and filters out files that
    cannot have relevant matches."""
    git_ls_files_out = subprocess.check_output(
        ["git", "-C", str(fuchsia_dir), "ls-files"], text=True
    )

    for line in git_ls_files_out.splitlines():
        path = pathlib.Path(line)
        if all(
            [
                path not in IGNORED_RELATIVE_PATHS,
                not path.is_dir(),
                any(p.path_matches(path) for p in PATTERNS),
            ]
        ):
            yield path


def do_subsitituion(path: pathlib.Path, new_api_level: str) -> None:
    """Replaces `NEXT` with new_api_level in the given file."""
    try:
        with path.open() as f:
            contents = f.read()
    except UnicodeDecodeError:
        print("Encountered binary file: " + str(path))
        return

    new_contents = contents
    for p in PATTERNS:
        if p.path_matches(path):
            new_contents = p.substitute(new_contents, new_api_level)

    if new_contents != contents:
        with path.open("w") as f:
            f.write(new_contents)


def main() -> None:
    parser = argparse.ArgumentParser(description=__doc__)
    parser.add_argument("--fuchsia-dir", type=pathlib.Path, required=True)
    parser.add_argument("--new-api-level", type=str, required=True)

    args = parser.parse_args()

    with concurrent.futures.ThreadPoolExecutor() as exe:
        # Use `list` to drain the iterator.
        list(
            exe.map(
                lambda path: do_subsitituion(path, args.new_api_level),
                get_git_files_for_substitution(args.fuchsia_dir),
            )
        )


if __name__ == "__main__":
    main()
