# Copyright (C) 2021 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 tool for generating manual page for all repo commands.

Most code lives in this module so it can be unittested.
"""

from pathlib import Path
from functools import partial
import argparse
import multiprocessing
import os
import re
import shutil
import subprocess
import sys
import tempfile

TOPDIR = Path(__file__).resolve().parent.parent
MANDIR = TOPDIR.joinpath("man")

# Load repo local modules.
sys.path.insert(0, str(TOPDIR))
from git_command import RepoSourceVersion
import subcmds


def worker(cmd, **kwargs):
    subprocess.run(cmd, **kwargs)


def main(argv):
    parser = argparse.ArgumentParser(description=__doc__)
    parser.parse_args(argv)

    if not shutil.which("help2man"):
        sys.exit("Please install help2man to continue.")

    # Let repo know we're generating man pages so it can avoid some dynamic
    # behavior (like probing active number of CPUs).  We use a weird name &
    # value to make it less likely for users to set this var themselves.
    os.environ["_REPO_GENERATE_MANPAGES_"] = " indeed! "

    # "repo branch" is an alias for "repo branches".
    del subcmds.all_commands["branch"]
    (MANDIR / "repo-branch.1").write_text(".so man1/repo-branches.1")

    version = RepoSourceVersion()
    cmdlist = [
        [
            "help2man",
            "-N",
            "-n",
            f"repo {cmd} - manual page for repo {cmd}",
            "-S",
            f"repo {cmd}",
            "-m",
            "Repo Manual",
            f"--version-string={version}",
            "-o",
            MANDIR.joinpath(f"repo-{cmd}.1.tmp"),
            "./repo",
            "-h",
            f"help {cmd}",
        ]
        for cmd in subcmds.all_commands
    ]
    cmdlist.append(
        [
            "help2man",
            "-N",
            "-n",
            "repository management tool built on top of git",
            "-S",
            "repo",
            "-m",
            "Repo Manual",
            f"--version-string={version}",
            "-o",
            MANDIR.joinpath("repo.1.tmp"),
            "./repo",
            "-h",
            "--help-all",
        ]
    )

    with tempfile.TemporaryDirectory() as tempdir:
        tempdir = Path(tempdir)
        repo_dir = tempdir / ".repo"
        repo_dir.mkdir()
        (repo_dir / "repo").symlink_to(TOPDIR)

        # Create a repo wrapper using the active Python executable.  We can't
        # pass this directly to help2man as it's too simple, so insert it via
        # shebang.
        data = (TOPDIR / "repo").read_text(encoding="utf-8")
        tempbin = tempdir / "repo"
        tempbin.write_text(f"#!{sys.executable}\n" + data, encoding="utf-8")
        tempbin.chmod(0o755)

        # Run all cmd in parallel, and wait for them to finish.
        with multiprocessing.Pool() as pool:
            pool.map(partial(worker, cwd=tempdir, check=True), cmdlist)

    for tmp_path in MANDIR.glob("*.1.tmp"):
        path = tmp_path.parent / tmp_path.stem
        old_data = path.read_text() if path.exists() else ""

        data = tmp_path.read_text()
        tmp_path.unlink()

        data = replace_regex(data)

        # If the only thing that changed was the date, don't refresh.  This
        # avoids a lot of noise when only one file actually updates.
        old_data = re.sub(
            r'^(\.TH REPO "1" ")([^"]+)', r"\1", old_data, flags=re.M
        )
        new_data = re.sub(r'^(\.TH REPO "1" ")([^"]+)', r"\1", data, flags=re.M)
        if old_data != new_data:
            path.write_text(data)


def replace_regex(data):
    """Replace semantically null regexes in the data.

    Args:
        data: manpage text.

    Returns:
        Updated manpage text.
    """
    regex = (
        (r"(It was generated by help2man) [0-9.]+", r"\g<1>."),
        (r"^\033\[[0-9;]*m([^\033]*)\033\[m", r"\g<1>"),
        (r"^\.IP\n(.*:)\n", r".SS \g<1>\n"),
        (r"^\.PP\nDescription", r".SH DETAILS"),
    )
    for pattern, replacement in regex:
        data = re.sub(pattern, replacement, data, flags=re.M)
    return data
