#!/usr/bin/env/python3

# Copyright 2021 The Chromium Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

# See BUILD.gn in this directory for an explanation of what this script is for.

import argparse
import os
import stat
import sys
import shutil
import subprocess
import re

from collections import defaultdict

EXPECTED_STDLIB_INPUT_REGEX = re.compile(r"([0-9a-z_]+)(?:-([0-9]+))?$")
RLIB_NAME_REGEX = re.compile(r"lib([0-9a-z_]+)-([0-9a-f]+)\.rlib$")


def main():
  parser = argparse.ArgumentParser("find_std_rlibs.py")
  parser.add_argument("--rust-bin-dir",
                      help="Path to Rust binaries",
                      required=True),
  parser.add_argument("--target", help="Rust target triple", required=False),
  parser.add_argument("--output",
                      help="Path to rlibs without suffixes",
                      required=True)
  parser.add_argument("--depfile", help="Path to write depfile", required=True)
  parser.add_argument("--depfile-target",
                      help="Target to key depfile around",
                      required=True)
  parser.add_argument("--stdlibs",
                      help="Expected list of standard library libraries")
  parser.add_argument("--ignore-stdlibs",
                      help="List of sysroot libraries to ignore")
  parser.add_argument("--extra-libs",
                      help="List of extra non-libstd sysroot libraries")
  parser.add_argument("--rustc-revision",
                      help="Not used, just passed from GN to add a dependency"
                      " on the rustc version.")
  args = parser.parse_args()

  # Expected rlibs by concise name (the crate name, plus a disambiguating suffix
  # e.g. "-2" when necessary).
  if args.stdlibs:
    rlibs_expected = set()
    for lib in args.stdlibs.split(','):
      # The version is only included if there's more than one of `name`, and
      # even then is only included for the 2nd onward.
      (name, version) = EXPECTED_STDLIB_INPUT_REGEX.match(lib).group(1, 2)
      if version is None:
        rlibs_expected.add(name)
      else:
        rlibs_expected.add(f"{name}-{version}")
    ignore_rlibs = set()
    if args.ignore_stdlibs is not None:
      ignore_rlibs = set(args.ignore_stdlibs.split(','))
  else:
    rlibs_expected = None

  extra_libs = set()
  if args.extra_libs:
    for lib in args.extra_libs.split(','):
      extra_libs.add(lib)

  # Ask rustc where to find the stdlib for this target.
  rustc = os.path.join(args.rust_bin_dir, "rustc")
  rustc_args = [rustc, "--print", "target-libdir"]
  if args.target:
    rustc_args.extend(["--target", args.target])
  rustlib_dir = subprocess.check_output(rustc_args).rstrip().decode()

  # Copy the rlibs to a predictable location. Whilst we're doing so,
  # also write a .d file so that ninja knows it doesn't need to do this
  # again unless the source rlibs change.
  # Format:
  # <output path to>/lib<lib name.rlib>: <path to each Rust stlib rlib>
  with open(args.depfile, 'w') as depfile:
    # Ninja isn't versatile at understanding depfiles. We have to say that a
    # single output depends on all the inputs. We choose any one of the
    # output rlibs for that purpose. If any of the input rlibs change, ninja
    # will run this script again and we'll copy them all afresh.
    depfile.write(
        "%s:" % (os.path.join(args.output, "lib%s.rlib" % args.depfile_target)))

    def copy_file(infile, outfile):
      depfile.write(f" {infile}")
      if (not os.path.exists(outfile)
          or os.stat(infile).st_mtime != os.stat(outfile).st_mtime):
        if os.path.exists(outfile):
          st = os.stat(outfile)
          os.chmod(outfile, st.st_mode | stat.S_IWUSR)
        shutil.copy(infile, outfile)

    # Each rlib is named "lib<crate_name>-<metadata>.rlib". The metadata
    # disambiguates multiple crates of the same name. We want to throw away the
    # metadata and use stable names. To do so, we replace the metadata bit with
    # a simple number 1, 2, etc. It doesn't matter how we assign these numbers
    # as long as it's consistent for a particular set of rlibs.

    # The rlib names present in the Rust distribution, including metadata. We
    # sort this list so crates of the same name are ordered by metadata. Also
    # filter out names that aren't rlibs.
    rlibs_present = [
        name for name in os.listdir(rustlib_dir) if name.endswith('.rlib')
    ]
    rlibs_present.sort()

    # Keep a count of the instances a crate name, so we can disambiguate the
    # rlibs with an incrementing number at the end.
    rlibs_seen = defaultdict(lambda: 0)

    for f in rlibs_present:
      # As standard Rust includes a hash on the end of each filename
      # representing certain metadata, to ensure that clients will link
      # against the correct version. As gn will be manually passing
      # the correct file path to our linker invocations, we don't need
      # that, and it would prevent us having the predictable filenames
      # which we need for statically computable gn dependency rules.
      (crate_name, metadata) = RLIB_NAME_REGEX.match(f).group(1, 2)

      # Use the number of times we've seen this name to disambiguate the output
      # filenames. Since we sort the input filenames including the metadata,
      # this will be the same every time.
      #
      # Only append the times seen if it is greater than 1. This allows the
      # BUILD.gn file to avoid adding '-1' to every name if there's only one
      # version of a particular one.
      rlibs_seen[crate_name] += 1
      if rlibs_seen[crate_name] == 1:
        concise_name = crate_name
      else:
        concise_name = "%s-%d" % (crate_name, rlibs_seen[crate_name])

      output_filename = f"lib{concise_name}.rlib"

      if rlibs_expected is not None:
        if concise_name in ignore_rlibs:
          continue
        if concise_name not in rlibs_expected:
          raise Exception("Found stdlib rlib that wasn't expected: %s" % f)
        rlibs_expected.remove(concise_name)

      infile = os.path.join(rustlib_dir, f)
      outfile = os.path.join(args.output, output_filename)
      copy_file(infile, outfile)

    for f in extra_libs:
      infile = os.path.join(rustlib_dir, f)
      outfile = os.path.join(args.output, f)
      copy_file(infile, outfile)

    depfile.write("\n")
    if rlibs_expected:
      raise Exception("We failed to find all expected stdlib rlibs: %s" %
                      ','.join(rlibs_expected))


if __name__ == '__main__':
  sys.exit(main())
