#!/usr/bin/env python3

import argparse
import itertools
import os
import subprocess
import sys

def get_build_var(var):
  return subprocess.run(["build/soong/soong_ui.bash","--dumpvar-mode", var],
                        check=True, capture_output=True, text=True).stdout.strip()


def get_all_modules():
  product_out = subprocess.run(["build/soong/soong_ui.bash", "--dumpvar-mode", "--abs", "PRODUCT_OUT"],
                                check=True, capture_output=True, text=True).stdout.strip()
  result = subprocess.run(["cat", product_out + "/all_modules.txt"], check=True, capture_output=True, text=True)
  return result.stdout.strip().split("\n")


def batched(iterable, n):
  # introduced in itertools 3.12, could delete once that's universally available
  if n < 1:
    raise ValueError('n must be at least one')
  it = iter(iterable)
  while batch := tuple(itertools.islice(it, n)):
    yield batch


def get_sources(modules):
  sources = set()
  for module_group in batched(modules, 40_000):
    result = subprocess.run(["./prebuilts/build-tools/linux-x86/bin/ninja", "-f",
                            "out/combined-" + os.environ["TARGET_PRODUCT"] + ".ninja",
                            "-t", "inputs", "-d", ] + list(module_group),
                            stderr=subprocess.STDOUT, stdout=subprocess.PIPE, check=False, text=True)
    if result.returncode != 0:
      sys.stderr.write(result.stdout)
      sys.exit(1)
    sources.update(set([f for f in result.stdout.split("\n") if not f.startswith("out/")]))
  return sources


def m_nothing():
  result = subprocess.run(["build/soong/soong_ui.bash", "--build-mode", "--all-modules",
                           "--dir=" + os.getcwd(), "nothing"],
                           check=False, stderr=subprocess.STDOUT, stdout=subprocess.PIPE, text=True)
  if result.returncode != 0:
    sys.stderr.write(result.stdout)
    sys.exit(1)


def get_git_dirs():
  text = subprocess.run(["repo","list"], check=True, capture_output=True, text=True).stdout
  return [line.split(" : ")[0] + "/" for line in text.split("\n")]


def get_referenced_projects(git_dirs, files):
  # files must be sorted
  referenced_dirs = set()
  prev_dir = None
  for f in files:
    # Optimization is ~5x speedup for large sets of files
    if prev_dir:
      if f.startswith(prev_dir):
        referenced_dirs.add(d)
        continue
    for d in git_dirs:
      if f.startswith(d):
        referenced_dirs.add(d)
        prev_dir = d
        break
  return referenced_dirs


def main(argv):
  # Argument parsing
  ap = argparse.ArgumentParser(description="List the required git projects for the given modules")
  ap.add_argument("--products", nargs="*",
                  help="One or more TARGET_PRODUCT to check, or \"*\" for all. If not provided"
                        + "just uses whatever has already been built")
  ap.add_argument("--variants", nargs="*",
                  help="The TARGET_BUILD_VARIANTS to check. If not provided just uses whatever has"
                        + " already been built, or eng if --products is supplied")
  ap.add_argument("--modules", nargs="*",
                  help="The build modules to check, or \"*\" for all, or droid if not supplied")
  ap.add_argument("--why", nargs="*",
                  help="Also print the input files used in these projects, or \"*\" for all")
  ap.add_argument("--unused", help="List the unused git projects for the given modules rather than"
                        + "the used ones. Ignores --why", action="store_true")
  args = ap.parse_args(argv[1:])

  modules = args.modules if args.modules else ["droid"]

  match args.products:
    case ["*"]:
      products = get_build_var("all_named_products").split(" ")
    case _:
      products = args.products

  # Get the list of sources for all of the requested build combos
  if not products and not args.variants:
    m_nothing()
    if args.modules == ["*"]:
      modules = get_all_modules()
    sources = get_sources(modules)
  else:
    if not products:
      sys.stderr.write("Error: --products must be supplied if --variants is supplied")
      sys.exit(1)
    sources = set()
    build_num = 1
    for product in products:
      os.environ["TARGET_PRODUCT"] = product
      variants = args.variants if args.variants else ["user", "userdebug", "eng"]
      for variant in variants:
        sys.stderr.write(f"Analyzing build {build_num} of {len(products)*len(variants)}\r")
        os.environ["TARGET_BUILD_VARIANT"] = variant
        m_nothing()
        if args.modules == ["*"]:
          modules = get_all_modules()
        sources.update(get_sources(modules))
        build_num += 1
    sys.stderr.write("\n\n")

  sources = sorted(sources)

  if args.unused:
    # Print the list of git directories that don't contain sources
    used_git_dirs = set(get_git_dirs())
    for project in sorted(used_git_dirs.difference(set(get_referenced_projects(used_git_dirs, sources)))):
      print(project[0:-1])
  else:
    # Print the list of git directories that has one or more of the sources in it
    for project in sorted(get_referenced_projects(get_git_dirs(), sources)):
      print(project[0:-1])
      if args.why:
        if "*" in args.why or project[0:-1] in args.why:
          prefix = project
          for f in sources:
            if f.startswith(prefix):
              print("  " + f)


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


# vim: set ts=2 sw=2 sts=2 expandtab nocindent tw=100:
