#!/usr/bin/env python3

import argparse
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_sources(modules):
  result = subprocess.run(["./prebuilts/build-tools/linux-x86/bin/ninja", "-f",
                           "out/combined-" + os.environ["TARGET_PRODUCT"] + ".ninja",
                           "-t", "inputs", "-d", ] + modules,
                          stderr=subprocess.STDOUT, stdout=subprocess.PIPE, check=False, text=True)
  if result.returncode != 0:
    sys.stderr.write(result.stdout)
    sys.exit(1)
  return set([f for f in result.stdout.split("\n") if not f.startswith("out/")])


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 [d[0:-1] for d in 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="The TARGET_PRODUCT to check. 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 droid it not supplied")
  ap.add_argument("--why", nargs="*",
                  help="Also print the input files used in these projects, or \"*\" for all")
  args = ap.parse_args(argv[1:])

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

  # Get the list of sources for all of the requested build combos
  if not args.products and not args.variants:
    sources = get_sources(modules)
  else:
    if not args.products:
      sys.stderr.write("Error: --products must be supplied if --variants is supplied")
      sys.exit(1)
    sources = set()
    build_num = 1
    for product in args.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(args.products)*len(variants)}\r")
        os.environ["TARGET_BUILD_VARIANT"] = variant
        m_nothing()
        sources.update(get_sources(modules))
        build_num += 1
    sys.stderr.write("\n\n")

  sources = sorted(sources)

  # 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)
    if args.why:
      if "*" in args.why or project 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:
