#!/usr/bin/env python3
# Copyright 2022 The ChromiumOS Authors.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""Help creating a Rust ebuild with CRATES.

This script is meant to help someone creating a Rust ebuild of the type
currently used by sys-apps/ripgrep and sys-apps/rust-analyzer.

In these ebuilds, the CRATES variable is used to list all dependencies, rather
than creating an ebuild for each dependency. This style of ebuild can be used
for a crate which is only intended for use in the chromiumos SDK, and which has
many dependencies which otherwise won't be used.

To create such an ebuild, there are essentially two tasks that must be done:

1. Determine all transitive dependent crates and version and list them in the
CRATES variable. Ignore crates that are already included in the main crate's
repository.

2. Find which dependent crates are not already on a chromeos mirror, retrieve
them from crates.io, and upload them to `gs://chromeos-localmirror/distfiles`.

This script parses the crate's lockfile to list transitive dependent crates,
and either lists crates to be uploaded or actually uploads them.

Of course these can be done manually instead. If you choose to do these steps
manually, I recommend *not* using the `cargo download` tool, and instead obtain
dependent crates at
`https://crates.io/api/v1/crates/{crate_name}/{crate_version}/download`.

Example usage:

    # Here we instruct the script to ignore crateA and crateB, presumably
    # because they are already included in the same repository as some-crate.
    # This will not actually upload any crates to `gs`.
    python3 crate_ebuild_help.py --lockfile some-crate/Cargo.lock \
            --ignore crateA --ignore crateB --dry-run

    # Similar to the above, but here we'll actually carry out the uploads.
    python3 crate_ebuild_help.py --lockfile some-crate/Cargo.lock \
            --ignore crateA --ignore crateB

See the ebuild files for ripgrep or rust-analyzer for other details.
"""

import argparse
import concurrent.futures
from pathlib import Path
import subprocess
import tempfile
from typing import List, Tuple
import urllib.request

# Python 3.11 has `tomllib`, so maybe eventually we can switch to that.
import toml


def run(args: List[str]) -> bool:
  result = subprocess.run(args,
                          stdout=subprocess.PIPE,
                          stderr=subprocess.PIPE,
                          check=False)
  return result.returncode == 0


def run_check(args: List[str]):
  subprocess.run(args,
                 stdout=subprocess.PIPE,
                 stderr=subprocess.PIPE,
                 check=True)


def gs_address_exists(address: str) -> bool:
  # returns False if the file isn't there
  return run(['gsutil.py', 'ls', address])


def crate_already_uploaded(crate_name: str, crate_version: str) -> bool:
  filename = f'{crate_name}-{crate_version}.crate'
  return gs_address_exists(
      f'gs://chromeos-localmirror/distfiles/{filename}') or gs_address_exists(
          f'gs://chromeos-mirror/gentoo/distfiles/{filename}')


def download_crate(crate_name: str, crate_version: str, localpath: Path):
  urllib.request.urlretrieve(
      f'https://crates.io/api/v1/crates/{crate_name}/{crate_version}/download',
      localpath)


def upload_crate(crate_name: str, crate_version: str, localpath: Path):
  run_check([
      'gsutil.py', 'cp', '-n', '-a', 'public-read',
      str(localpath),
      f'gs://chromeos-localmirror/distfiles/{crate_name}-{crate_version}.crate'
  ])


def main():
  parser = argparse.ArgumentParser(
      description='Help prepare a Rust crate for an ebuild.')
  parser.add_argument('--lockfile',
                      type=str,
                      required=True,
                      help='Path to the lockfile of the crate in question.')
  parser.add_argument(
      '--ignore',
      type=str,
      action='append',
      required=False,
      default=[],
      help='Ignore the crate by this name (may be used multiple times).')
  parser.add_argument(
      '--dry-run',
      action='store_true',
      help="Don't actually download/upload crates, just print their names.")
  ns = parser.parse_args()

  to_ignore = set(ns.ignore)

  toml_contents = toml.load(ns.lockfile)
  packages = toml_contents['package']

  crates = [(pkg['name'], pkg['version']) for pkg in packages
            if pkg['name'] not in to_ignore]
  crates.sort()

  print('Dependent crates:')
  for name, version in crates:
    print(f'{name}-{version}')
  print()

  if ns.dry_run:
    print('Crates that would be uploaded (skipping ones already uploaded):')
  else:
    print('Uploading crates (skipping ones already uploaded):')

  def maybe_upload(crate: Tuple[str, str]) -> str:
    name, version = crate
    if crate_already_uploaded(name, version):
      return ''
    if not ns.dry_run:
      with tempfile.TemporaryDirectory() as temp_dir:
        path = Path(temp_dir.name, f'{name}-{version}.crate')
        download_crate(name, version, path)
        upload_crate(name, version, path)
    return f'{name}-{version}'

  # Simple benchmarking on my machine with rust-analyzer's Cargo.lock, using
  # the --dry-run option, gives a wall time of 277 seconds with max_workers=1
  # and 70 seconds with max_workers=4.
  with concurrent.futures.ThreadPoolExecutor(max_workers=4) as executor:
    crates_len = len(crates)
    for i, s in enumerate(executor.map(maybe_upload, crates)):
      if s:
        j = i + 1
        print(f'[{j}/{crates_len}] {s}')
  print()


if __name__ == '__main__':
  main()
