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

This is intended to be run before every official Repo release.
"""

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__)
  opts = 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'), TOPDIR.joinpath('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'), TOPDIR.joinpath('repo'),
    '-h', '--help-all'])

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

    # 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)

  regex = (
      (r'(It was generated by help2man) [0-9.]+', '\g<1>.'),
      (r'^\.IP\n(.*:)\n', '.SS \g<1>\n'),
      (r'^\.PP\nDescription', '.SH DETAILS'),
  )
  for path in MANDIR.glob('*.1'):
    data = path.read_text()
    for pattern, replacement in regex:
      data = re.sub(pattern, replacement, data, flags=re.M)
    path.write_text(data)

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