#!/usr/bin/env python3
# Copyright 2016 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.

"""Helper script to quickly update the bundled cpplint.py script."""

import argparse
import json
from pathlib import Path
import re
import sys
import urllib.request


# Since this is manually run by repohooks developers, we can safely require more
# recent versions of Python.
assert sys.version_info >= (3, 9), f"Python 3.9+ required; found {sys.version}"


THIS_FILE = Path(__file__).resolve()
SCRIPT_NAME = THIS_FILE.name
THIS_DIR = THIS_FILE.parent
CPPLINT_PY = THIS_DIR / "cpplint.py"


# The cpplint project.
GITHUB_URL = "https://github.com/cpplint/cpplint/raw"


def find_latest_tag() -> str:
    """Figure out the latest tag/release and return its commit."""
    url = "https://api.github.com/repos/cpplint/cpplint/tags"
    with urllib.request.urlopen(url, timeout=60) as fp:
        data = fp.read()

    # This will have the format:
    # [
    #   {"name": "0.0.7", "commit": {"sha": "<sha1>", ...}, ...},
    #   {"name": "0.0.6", "commit": {"sha": "<sha1>", ...}, ...},
    #   ...
    # ]
    resp = json.loads(data)
    # Filter out random named tags.
    tags = [x for x in resp if re.match(r"^[0-9.]+$", x["name"])]
    tags = sorted(
        tags,
        key=lambda x: tuple(int(v) for v in x["name"].split(".")),
        reverse=True,
    )
    latest = tags[0]
    print(f"{SCRIPT_NAME}: found latest tag {latest['name']}")
    return latest["commit"]["sha"]


def download(commit: str) -> str:
    """Download latest cpplint version."""
    url = f"{GITHUB_URL}/{commit}/cpplint.py"
    with urllib.request.urlopen(url, timeout=60) as fp:
        return fp.read()


def munge_content(data: str) -> str:
    """Make changes to |data| for local script usage."""
    lines = data.splitlines()
    if lines[0].endswith(b"python"):
        lines[0] += b"3"
    lines.insert(1, b"# pylint: skip-file")
    return b"\n".join(lines).rstrip() + b"\n"


def update_script(data: str) -> None:
    """Update the cpplint script."""
    CPPLINT_PY.write_bytes(data)
    CPPLINT_PY.chmod(0o755)


def get_parser() -> argparse.ArgumentParser:
    """Return a command line parser."""
    parser = argparse.ArgumentParser(description=__doc__)
    parser.add_argument(
        "--rev",
        help="What git commit or ref to fetch (default: latest)",
    )
    return parser


def main(argv: list[str]) -> int:
    parser = get_parser()
    opts = parser.parse_args(argv)

    ret = 0

    commit = opts.rev
    if not commit:
        commit = find_latest_tag()
    data = download(commit)
    data = munge_content(data)
    update_script(data)

    return ret


if __name__ == "__main__":
    sys.exit(main(sys.argv[1:]))
