#!/usr/bin/env python3
# Copyright (C) 2019 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.

"""Wrapper to run linters and pytest with the right settings."""

import functools
import os
import shlex
import shutil
import subprocess
import sys


# NB: While tests/* support Python >=3.6 to match requirements.json for `repo`,
# the higher level runner logic does not need to be held back.
assert sys.version_info >= (3, 9), "Test/release framework requires Python 3.9+"


ROOT_DIR = os.path.dirname(os.path.realpath(__file__))


def log_cmd(cmd: str, argv: list[str]) -> None:
    """Log a debug message to make history easier to track."""
    print("+", cmd, shlex.join(argv), file=sys.stderr)


@functools.lru_cache()
def is_ci() -> bool:
    """Whether we're running in our CI system."""
    return os.getenv("LUCI_CQ") == "yes"


def run_pytest(argv: list[str]) -> int:
    """Returns the exit code from pytest."""
    if is_ci():
        argv = ["-m", "not skip_cq"] + argv

    log_cmd("pytest", argv)
    return subprocess.run(
        [sys.executable, "-m", "pytest"] + argv,
        check=False,
        cwd=ROOT_DIR,
    ).returncode


def run_pytest_py38(argv: list[str]) -> int:
    """Returns the exit code from pytest under Python 3.8."""
    if is_ci():
        argv = ["-m", "not skip_cq"] + argv

    log_cmd("[vpython 3.8] pytest", argv)
    try:
        return subprocess.run(
            [
                "vpython3",
                "-vpython-spec",
                "run_tests.vpython3.8",
                "-m",
                "pytest",
            ]
            + argv,
            check=False,
            cwd=ROOT_DIR,
        ).returncode
    except FileNotFoundError:
        # Skip if the user doesn't have vpython from depot_tools.
        return 0


def run_black():
    """Returns the exit code from black."""
    argv = ["--version"]
    log_cmd("black", argv)
    subprocess.run(
        [sys.executable, "-m", "black"] + argv,
        check=True,
        cwd=ROOT_DIR,
    )

    # Black by default only matches .py files.  We have to list standalone
    # scripts manually.
    extra_programs = [
        "repo",
        "run_tests",
        "release/update-hooks",
        "release/update-manpages",
    ]
    argv = ["--diff", "--check", ROOT_DIR] + extra_programs
    log_cmd("black", argv)
    return subprocess.run(
        [sys.executable, "-m", "black"] + argv,
        check=False,
        cwd=ROOT_DIR,
    ).returncode


def run_flake8():
    """Returns the exit code from flake8."""
    argv = ["--version"]
    log_cmd("flake8", argv)
    subprocess.run(
        [sys.executable, "-m", "flake8"] + argv,
        check=True,
        cwd=ROOT_DIR,
    )

    argv = [ROOT_DIR]
    log_cmd("flake8", argv)
    return subprocess.run(
        [sys.executable, "-m", "flake8"] + argv,
        check=False,
        cwd=ROOT_DIR,
    ).returncode


def run_isort():
    """Returns the exit code from isort."""
    argv = ["--version-number"]
    log_cmd("isort", argv)
    subprocess.run(
        [sys.executable, "-m", "isort"] + argv,
        check=True,
        cwd=ROOT_DIR,
    )

    argv = ["--check", ROOT_DIR]
    log_cmd("isort", argv)
    return subprocess.run(
        [sys.executable, "-m", "isort"] + argv,
        check=False,
        cwd=ROOT_DIR,
    ).returncode


def run_check_metadata():
    """Returns the exit code from check-metadata."""
    argv = []
    log_cmd("release/check-metadata.py", argv)
    return subprocess.run(
        [sys.executable, "release/check-metadata.py"] + argv,
        check=False,
        cwd=ROOT_DIR,
    ).returncode


def run_update_manpages() -> int:
    """Returns the exit code from release/update-manpages."""
    argv = ["--check"]
    log_cmd("release/update-manpages", argv)
    return subprocess.run(
        [sys.executable, "release/update-manpages"] + argv,
        check=False,
        cwd=ROOT_DIR,
    ).returncode


def cipd_bootstrap() -> None:
    """Install packages via cipd if available."""
    argv = ["ensure", "-root", ".cipd_bin", "-ensure-file", "cipd_manifest.txt"]
    log_cmd("cipd", argv)
    try:
        subprocess.run(
            ["cipd"] + argv,
            check=True,
            cwd=ROOT_DIR,
        )
    except FileNotFoundError:
        # Skip if the user doesn't have cipd from depot_tools.
        return


def main(argv):
    """The main entry."""
    cipd_bootstrap()
    checks = (
        functools.partial(run_pytest, argv),
        functools.partial(run_pytest_py38, argv),
        run_black,
        run_flake8,
        run_isort,
        run_check_metadata,
        run_update_manpages,
    )
    # Run all the tests all the time to get full feedback.  Don't exit on the
    # first error as that makes it more difficult to iterate in the CQ.
    return 1 if sum(c() for c in checks) else 0


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