#!/usr/bin/env python3

"""
Command to print info about makefiles remaining to be converted to soong.

See usage / argument parsing below for commandline options.
"""

import argparse
import csv
import itertools
import json
import os
import re
import sys

DIRECTORY_PATTERNS = [x.split("/") for x in (
  "device/*",
  "frameworks/*",
  "hardware/*",
  "packages/*",
  "vendor/*",
  "*",
)]

def match_directory_group(pattern, filename):
  match = []
  filename = filename.split("/")
  if len(filename) < len(pattern):
    return None
  for i in range(len(pattern)):
    pattern_segment = pattern[i]
    filename_segment = filename[i]
    if pattern_segment == "*" or pattern_segment == filename_segment:
      match.append(filename_segment)
    else:
      return None
  if match:
    return os.path.sep.join(match)
  else:
    return None

def directory_group(filename):
  for pattern in DIRECTORY_PATTERNS:
    match = match_directory_group(pattern, filename)
    if match:
      return match
  return os.path.dirname(filename)

class Analysis(object):
  def __init__(self, filename, line_matches):
    self.filename = filename;
    self.line_matches = line_matches

def analyze_lines(filename, lines, func):
  line_matches = []
  for i in range(len(lines)):
    line = lines[i]
    stripped = line.strip()
    if stripped.startswith("#"):
      continue
    if func(stripped):
      line_matches.append((i+1, line))
  if line_matches:
    return Analysis(filename, line_matches);

def analyze_has_conditional(line):
  return (line.startswith("ifeq") or line.startswith("ifneq")
          or line.startswith("ifdef") or line.startswith("ifndef"))

NORMAL_INCLUDES = [re.compile(pattern) for pattern in (
  "include \$+\(CLEAR_VARS\)", # These are in defines which are tagged separately
  "include \$+\(BUILD_.*\)",
  "include \$\(call first-makefiles-under, *\$\(LOCAL_PATH\)\)",
  "include \$\(call all-subdir-makefiles\)",
  "include \$\(all-subdir-makefiles\)",
  "include \$\(call all-makefiles-under, *\$\(LOCAL_PATH\)\)",
  "include \$\(call all-makefiles-under, *\$\(call my-dir\).*\)",
  "include \$\(BUILD_SYSTEM\)/base_rules.mk", # called out separately
  "include \$\(call all-named-subdir-makefiles,.*\)",
  "include \$\(subdirs\)",
)]
def analyze_has_wacky_include(line):
  if not (line.startswith("include") or line.startswith("-include")
          or line.startswith("sinclude")):
    return False
  for matcher in NORMAL_INCLUDES:
    if matcher.fullmatch(line):
      return False
  return True

BASE_RULES_RE = re.compile("include \$\(BUILD_SYSTEM\)/base_rules.mk")

class Analyzer(object):
  def __init__(self, title, func):
    self.title = title;
    self.func = func


ANALYZERS = (
  Analyzer("ifeq / ifneq", analyze_has_conditional),
  Analyzer("Wacky Includes", analyze_has_wacky_include),
  Analyzer("Calls base_rules", lambda line: BASE_RULES_RE.fullmatch(line)),
  Analyzer("Calls define", lambda line: line.startswith("define ")),
  Analyzer("Has ../", lambda line: "../" in line),
  Analyzer("dist-for-&#8203;goals", lambda line: "dist-for-goals" in line),
  Analyzer(".PHONY", lambda line: ".PHONY" in line),
  Analyzer("render-&#8203;script", lambda line: ".rscript" in line),
  Analyzer("vts src", lambda line: ".vts" in line),
  Analyzer("COPY_&#8203;HEADERS", lambda line: "LOCAL_COPY_HEADERS" in line),
)

class Summary(object):
  def __init__(self):
    self.makefiles = dict()
    self.directories = dict()

  def Add(self, makefile):
    self.makefiles[makefile.filename] = makefile
    self.directories.setdefault(directory_group(makefile.filename), []).append(makefile)

class Makefile(object):
  def __init__(self, filename):
    self.filename = filename

    # Analyze the file
    with open(filename, "r", errors="ignore") as f:
      try:
        lines = f.readlines()
      except UnicodeDecodeError as ex:
        sys.stderr.write("Filename: %s\n" % filename)
        raise ex
    lines = [line.strip() for line in lines]

    self.analyses = dict([(analyzer, analyze_lines(filename, lines, analyzer.func)) for analyzer
        in ANALYZERS])

def find_android_mk():
  cwd = os.getcwd()
  for root, dirs, files in os.walk(cwd):
    for filename in files:
      if filename == "Android.mk":
        yield os.path.join(root, filename)[len(cwd) + 1:]
    for ignore in (".git", ".repo"):
      if ignore in dirs:
        dirs.remove(ignore)

def is_aosp(dirname):
  for d in ("device/sample", "hardware/interfaces", "hardware/libhardware",
          "hardware/ril"):
    if dirname.startswith(d):
      return True
  for d in ("device/", "hardware/", "vendor/"):
    if dirname.startswith(d):
      return False
  return True

def is_google(dirname):
  for d in ("device/google",
            "hardware/google",
            "test/sts",
            "vendor/auto",
            "vendor/google",
            "vendor/unbundled_google",
            "vendor/widevine",
            "vendor/xts"):
    if dirname.startswith(d):
      return True
  return False

def is_clean(makefile):
  for analysis in makefile.analyses.values():
    if analysis:
      return False
  return True

def clean_and_only_blocked_by_clean(soong, all_makefiles, makefile):
  if not is_clean(makefile):
    return False
  modules = soong.reverse_makefiles[makefile.filename]
  for module in modules:
    for dep in soong.transitive_deps(module):
      for filename in soong.makefiles.get(dep, []):
        m = all_makefiles.get(filename)
        if m and not is_clean(m):
          return False
  return True

class Annotations(object):
  def __init__(self):
    self.entries = []
    self.count = 0

  def Add(self, makefiles, modules):
    self.entries.append((makefiles, modules))
    self.count += 1
    return self.count-1

class SoongData(object):
  def __init__(self, reader):
    """Read the input file and store the modules and dependency mappings.
    """
    self.problems = dict()
    self.deps = dict()
    self.reverse_deps = dict()
    self.module_types = dict()
    self.makefiles = dict()
    self.reverse_makefiles = dict()
    self.installed = dict()
    self.reverse_installed = dict()
    self.modules = set()

    for (module, module_type, problem, dependencies, makefiles, installed) in reader:
      self.modules.add(module)
      makefiles = [f for f in makefiles.strip().split(' ') if f != ""]
      self.module_types[module] = module_type
      self.problems[module] = problem
      self.deps[module] = [d for d in dependencies.strip().split(' ') if d != ""]
      for dep in self.deps[module]:
        if not dep in self.reverse_deps:
          self.reverse_deps[dep] = []
        self.reverse_deps[dep].append(module)
      self.makefiles[module] = makefiles
      for f in makefiles:
        self.reverse_makefiles.setdefault(f, []).append(module)
      for f in installed.strip().split(' '):
        self.installed[f] = module
        self.reverse_installed.setdefault(module, []).append(f)

  def transitive_deps(self, module):
    results = set()
    def traverse(module):
      for dep in self.deps.get(module, []):
        if not dep in results:
          results.add(dep)
          traverse(module)
    traverse(module)
    return results

  def contains_unblocked_modules(self, filename):
    for m in self.reverse_makefiles[filename]:
      if len(self.deps[m]) == 0:
        return True
    return False

  def contains_blocked_modules(self, filename):
    for m in self.reverse_makefiles[filename]:
      if len(self.deps[m]) > 0:
        return True
    return False

def count_deps(depsdb, module, seen):
  """Based on the depsdb, count the number of transitive dependencies.

  You can pass in an reversed dependency graph to count the number of
  modules that depend on the module."""
  count = 0
  seen.append(module)
  if module in depsdb:
    for dep in depsdb[module]:
      if dep in seen:
        continue
      count += 1 + count_deps(depsdb, dep, seen)
  return count

OTHER_PARTITON = "_other"
HOST_PARTITON = "_host"

def get_partition_from_installed(HOST_OUT_ROOT, PRODUCT_OUT, filename):
  host_prefix = HOST_OUT_ROOT + "/"
  device_prefix = PRODUCT_OUT + "/"

  if filename.startswith(host_prefix):
    return HOST_PARTITON

  elif filename.startswith(device_prefix):
    index = filename.find("/", len(device_prefix))
    if index < 0:
      return OTHER_PARTITON
    return filename[len(device_prefix):index]

  return OTHER_PARTITON

def format_module_link(module):
  return "<a class='ModuleLink' href='#module_%s'>%s</a>" % (module, module)

def format_module_list(modules):
  return "".join(["<div>%s</div>" % format_module_link(m) for m in modules])

def print_analysis_header(link, title):
  print("""
    <a name="%(link)s"></a>
    <h2>%(title)s</h2>
    <table>
      <tr>
        <th class="RowTitle">Directory</th>
        <th class="Count">Total</th>
        <th class="Count Clean">Easy</th>
        <th class="Count Clean">Unblocked Clean</th>
        <th class="Count Unblocked">Unblocked</th>
        <th class="Count Blocked">Blocked</th>
        <th class="Count Clean">Clean</th>
  """ % {
    "link": link,
    "title": title
  })
  for analyzer in ANALYZERS:
    print("""<th class="Count Warning">%s</th>""" % analyzer.title)
  print("      </tr>")

# get all modules in $(PRODUCT_PACKAGE) and the corresponding deps
def get_module_product_packages_plus_deps(initial_modules, result, soong_data):
  for module in initial_modules:
    if module in result:
      continue
    result.add(module)
    if module in soong_data.deps:
      get_module_product_packages_plus_deps(soong_data.deps[module], result, soong_data)

def main():
  parser = argparse.ArgumentParser(description="Info about remaining Android.mk files.")
  parser.add_argument("--device", type=str, required=True,
                      help="TARGET_DEVICE")
  parser.add_argument("--product-packages", type=argparse.FileType('r'),
                      default=None,
                      help="PRODUCT_PACKAGES")
  parser.add_argument("--title", type=str,
                      help="page title")
  parser.add_argument("--codesearch", type=str,
                      default="https://cs.android.com/android/platform/superproject/+/master:",
                      help="page title")
  parser.add_argument("--out-dir", type=str,
                      default=None,
                      help="Equivalent of $OUT_DIR, which will also be checked if"
                        + " --out-dir is unset. If neither is set, default is"
                        + " 'out'.")
  parser.add_argument("--mode", type=str,
                      default="html",
                      help="output format: csv or html")

  args = parser.parse_args()

  # Guess out directory name
  if not args.out_dir:
    args.out_dir = os.getenv("OUT_DIR", "out")
  while args.out_dir.endswith("/") and len(args.out_dir) > 1:
    args.out_dir = args.out_dir[:-1]

  TARGET_DEVICE = args.device
  global HOST_OUT_ROOT
  HOST_OUT_ROOT = args.out_dir + "/host"
  global PRODUCT_OUT
  PRODUCT_OUT = args.out_dir + "/target/product/%s" % TARGET_DEVICE

  # Read target information
  # TODO: Pull from configurable location. This is also slightly different because it's
  # only a single build, where as the tree scanning we do below is all Android.mk files.
  with open("%s/obj/PACKAGING/soong_conversion_intermediates/soong_conv_data"
      % PRODUCT_OUT, "r", errors="ignore") as csvfile:
    soong = SoongData(csv.reader(csvfile))

  # Read the makefiles
  all_makefiles = dict()
  for filename, modules in soong.reverse_makefiles.items():
    if filename.startswith(args.out_dir + "/"):
      continue
    all_makefiles[filename] = Makefile(filename)

  # Get all the modules in $(PRODUCT_PACKAGES) and the correspoding deps
  product_package_modules_plus_deps = set()
  if args.product_packages:
    product_package_top_modules = args.product_packages.read().strip().split('\n')
    get_module_product_packages_plus_deps(product_package_top_modules, product_package_modules_plus_deps, soong)

  if args.mode == "html":
    HtmlProcessor(args=args, soong=soong, all_makefiles=all_makefiles,
        product_packages_modules=product_package_modules_plus_deps).execute()
  elif args.mode == "csv":
    CsvProcessor(args=args, soong=soong, all_makefiles=all_makefiles,
        product_packages_modules=product_package_modules_plus_deps).execute()

class HtmlProcessor(object):
  def __init__(self, args, soong, all_makefiles, product_packages_modules):
    self.args = args
    self.soong = soong
    self.all_makefiles = all_makefiles
    self.product_packages_modules = product_packages_modules
    self.annotations = Annotations()

  def execute(self):
    if self.args.title:
      page_title = self.args.title
    else:
      page_title = "Remaining Android.mk files"

    # Which modules are installed where
    modules_by_partition = dict()
    partitions = set()
    for installed, module in self.soong.installed.items():
      if len(self.product_packages_modules) > 0 and module not in self.product_packages_modules:
        continue
      partition = get_partition_from_installed(HOST_OUT_ROOT, PRODUCT_OUT, installed)
      modules_by_partition.setdefault(partition, []).append(module)
      partitions.add(partition)

    print("""
    <html>
      <head>
        <title>%(page_title)s</title>
        <style type="text/css">
          body, table {
            font-family: Roboto, sans-serif;
            font-size: 9pt;
          }
          body {
            margin: 0;
            padding: 0;
            display: flex;
            flex-direction: column;
            height: 100vh;
          }
          #container {
            flex: 1;
            display: flex;
            flex-direction: row;
            overflow: hidden;
          }
          #tables {
            padding: 0 20px 40px 20px;
            overflow: scroll;
            flex: 2 2 600px;
          }
          #details {
            display: none;
            overflow: scroll;
            flex: 1 1 650px;
            padding: 0 20px 0 20px;
          }
          h1 {
            margin: 16px 0 16px 20px;
          }
          h2 {
            margin: 12px 0 4px 0;
          }
          .RowTitle {
            text-align: left;
            width: 200px;
            min-width: 200px;
          }
          .Count {
            text-align: center;
            width: 60px;
            min-width: 60px;
            max-width: 60px;
          }
          th.Clean,
          th.Unblocked {
            background-color: #1e8e3e;
          }
          th.Blocked {
            background-color: #d93025;
          }
          th.Warning {
            background-color: #e8710a;
          }
          th {
            background-color: #1a73e8;
            color: white;
            font-weight: bold;
          }
          td.Unblocked {
            background-color: #81c995;
          }
          td.Blocked {
            background-color: #f28b82;
          }
          td, th {
            padding: 2px 4px;
            border-right: 2px solid white;
          }
          tr.TotalRow td {
            background-color: white;
            border-right-color: white;
          }
          tr.AospDir td {
            background-color: #e6f4ea;
            border-right-color: #e6f4ea;
          }
          tr.GoogleDir td {
            background-color: #e8f0fe;
            border-right-color: #e8f0fe;
          }
          tr.PartnerDir td {
            background-color: #fce8e6;
            border-right-color: #fce8e6;
          }
          table {
            border-spacing: 0;
            border-collapse: collapse;
          }
          div.Makefile {
            margin: 12px 0 0 0;
          }
          div.Makefile:first {
            margin-top: 0;
          }
          div.FileModules {
            padding: 4px 0 0 20px;
          }
          td.LineNo {
            vertical-align: baseline;
            padding: 6px 0 0 20px;
            width: 50px;
            vertical-align: baseline;
          }
          td.LineText {
            vertical-align: baseline;
            font-family: monospace;
            padding: 6px 0 0 0;
          }
          a.CsLink {
            font-family: monospace;
          }
          div.Help {
            width: 550px;
          }
          table.HelpColumns tr {
            border-bottom: 2px solid white;
          }
          .ModuleName {
            vertical-align: baseline;
            padding: 6px 0 0 20px;
            width: 275px;
          }
          .ModuleDeps {
            vertical-align: baseline;
            padding: 6px 0 0 0;
          }
          table#Modules td {
            vertical-align: baseline;
          }
          tr.Alt {
            background-color: #ececec;
          }
          tr.Alt td {
            border-right-color: #ececec;
          }
          .AnalysisCol {
            width: 300px;
            padding: 2px;
            line-height: 21px;
          }
          .Analysis {
            color: white;
            font-weight: bold;
            background-color: #e8710a;
            border-radius: 6px;
            margin: 4px;
            padding: 2px 6px;
            white-space: nowrap;
          }
          .Nav {
            margin: 4px 0 16px 20px;
          }
          .NavSpacer {
            display: inline-block;
            width: 6px;
          }
          .ModuleDetails {
            margin-top: 20px;
          }
          .ModuleDetails td {
            vertical-align: baseline;
          }
        </style>
      </head>
      <body>
        <h1>%(page_title)s</h1>
        <div class="Nav">
          <a href='#help'>Help</a>
          <span class='NavSpacer'></span><span class='NavSpacer'> </span>
          Partitions:
    """ % {
      "page_title": page_title,
    })
    for partition in sorted(partitions):
      print("<a href='#partition_%s'>%s</a><span class='NavSpacer'></span>" % (partition, partition))

    print("""
          <span class='NavSpacer'></span><span class='NavSpacer'> </span>
          <a href='#summary'>Overall Summary</a>
        </div>
        <div id="container">
          <div id="tables">
          <a name="help"></a>
          <div class="Help">
            <p>
            This page analyzes the remaining Android.mk files in the Android Source tree.
            <p>
            The modules are first broken down by which of the device filesystem partitions
            they are installed to. This also includes host tools and testcases which don't
            actually reside in their own partition but convenitely group together.
            <p>
            The makefiles for each partition are further are grouped into a set of directories
            aritrarily picked to break down the problem size by owners.
            <ul style="width: 300px">
              <li style="background-color: #e6f4ea">AOSP directories are colored green.</li>
              <li style="background-color: #e8f0fe">Google directories are colored blue.</li>
              <li style="background-color: #fce8e6">Other partner directories are colored red.</li>
            </ul>
            Each of the makefiles are scanned for issues that are likely to come up during
            conversion to soong.  Clicking the number in each cell shows additional information,
            including the line that triggered the warning.
            <p>
            <table class="HelpColumns">
              <tr>
                <th>Total</th>
                <td>The total number of makefiles in this each directory.</td>
              </tr>
              <tr>
                <th class="Clean">Easy</th>
                <td>The number of makefiles that have no warnings themselves, and also
                    none of their dependencies have warnings either.</td>
              </tr>
              <tr>
                <th class="Clean">Unblocked Clean</th>
                <td>The number of makefiles that are both Unblocked and Clean.</td>
              </tr>

              <tr>
                <th class="Unblocked">Unblocked</th>
                <td>Makefiles containing one or more modules that don't have any
                    additional dependencies pending before conversion.</td>
              </tr>
              <tr>
                <th class="Blocked">Blocked</th>
                <td>Makefiles containiong one or more modules which <i>do</i> have
                    additional prerequesite depenedencies that are not yet converted.</td>
              </tr>
              <tr>
                <th class="Clean">Clean</th>
                <td>The number of makefiles that have none of the following warnings.</td>
              </tr>
              <tr>
                <th class="Warning">ifeq / ifneq</th>
                <td>Makefiles that use <code>ifeq</code> or <code>ifneq</code>. i.e.
                conditionals.</td>
              </tr>
              <tr>
                <th class="Warning">Wacky Includes</th>
                <td>Makefiles that <code>include</code> files other than the standard build-system
                    defined template and macros.</td>
              </tr>
              <tr>
                <th class="Warning">Calls base_rules</th>
                <td>Makefiles that include base_rules.mk directly.</td>
              </tr>
              <tr>
                <th class="Warning">Calls define</th>
                <td>Makefiles that define their own macros. Some of these are easy to convert
                    to soong <code>defaults</code>, but others are complex.</td>
              </tr>
              <tr>
                <th class="Warning">Has ../</th>
                <td>Makefiles containing the string "../" outside of a comment. These likely
                    access files outside their directories.</td>
              </tr>
              <tr>
                <th class="Warning">dist-for-goals</th>
                <td>Makefiles that call <code>dist-for-goals</code> directly.</td>
              </tr>
              <tr>
                <th class="Warning">.PHONY</th>
                <td>Makefiles that declare .PHONY targets.</td>
              </tr>
              <tr>
                <th class="Warning">renderscript</th>
                <td>Makefiles defining targets that depend on <code>.rscript</code> source files.</td>
              </tr>
              <tr>
                <th class="Warning">vts src</th>
                <td>Makefiles defining targets that depend on <code>.vts</code> source files.</td>
              </tr>
              <tr>
                <th class="Warning">COPY_HEADERS</th>
                <td>Makefiles using LOCAL_COPY_HEADERS.</td>
              </tr>
            </table>
            <p>
            Following the list of directories is a list of the modules that are installed on
            each partition. Potential issues from their makefiles are listed, as well as the
            total number of dependencies (both blocking that module and blocked by that module)
            and the list of direct dependencies.  Note: The number is the number of all transitive
            dependencies and the list of modules is only the direct dependencies.
          </div>
    """)

    overall_summary = Summary()

    # For each partition
    for partition in sorted(partitions):
      modules = modules_by_partition[partition]

      makefiles = set(itertools.chain.from_iterable(
          [self.soong.makefiles[module] for module in modules]))

      # Read makefiles
      summary = Summary()
      for filename in makefiles:
        makefile = self.all_makefiles.get(filename)
        if makefile:
          summary.Add(makefile)
          overall_summary.Add(makefile)

      # Categorize directories by who is responsible
      aosp_dirs = []
      google_dirs = []
      partner_dirs = []
      for dirname in sorted(summary.directories.keys()):
        if is_aosp(dirname):
          aosp_dirs.append(dirname)
        elif is_google(dirname):
          google_dirs.append(dirname)
        else:
          partner_dirs.append(dirname)

      print_analysis_header("partition_" + partition, partition)

      for dirgroup, rowclass in [(aosp_dirs, "AospDir"),
                                 (google_dirs, "GoogleDir"),
                                 (partner_dirs, "PartnerDir"),]:
        for dirname in dirgroup:
          self.print_analysis_row(summary, modules,
                               dirname, rowclass, summary.directories[dirname])

      self.print_analysis_row(summary, modules,
                           "Total", "TotalRow",
                           set(itertools.chain.from_iterable(summary.directories.values())))
      print("""
        </table>
      """)

      module_details = [(count_deps(self.soong.deps, m, []),
                         -count_deps(self.soong.reverse_deps, m, []), m)
                 for m in modules]
      module_details.sort()
      module_details = [m[2] for m in module_details]
      print("""
        <table class="ModuleDetails">""")
      print("<tr>")
      print("  <th>Module Name</th>")
      print("  <th>Issues</th>")
      print("  <th colspan='2'>Blocked By</th>")
      print("  <th colspan='2'>Blocking</th>")
      print("</tr>")
      altRow = True
      for module in module_details:
        analyses = set()
        for filename in self.soong.makefiles[module]:
          makefile = summary.makefiles.get(filename)
          if makefile:
            for analyzer, analysis in makefile.analyses.items():
              if analysis:
                analyses.add(analyzer.title)

        altRow = not altRow
        print("<tr class='%s'>" % ("Alt" if altRow else "",))
        print("  <td><a name='module_%s'></a>%s</td>" % (module, module))
        print("  <td class='AnalysisCol'>%s</td>" % " ".join(["<span class='Analysis'>%s</span>" % title
            for title in analyses]))
        print("  <td>%s</td>" % count_deps(self.soong.deps, module, []))
        print("  <td>%s</td>" % format_module_list(self.soong.deps.get(module, [])))
        print("  <td>%s</td>" % count_deps(self.soong.reverse_deps, module, []))
        print("  <td>%s</td>" % format_module_list(self.soong.reverse_deps.get(module, [])))
        print("</tr>")
      print("""</table>""")

    print_analysis_header("summary", "Overall Summary")

    modules = [module for installed, module in self.soong.installed.items()]
    self.print_analysis_row(overall_summary, modules,
                         "All Makefiles", "TotalRow",
                         set(itertools.chain.from_iterable(overall_summary.directories.values())))
    print("""
        </table>
    """)

    print("""
      <script type="text/javascript">
      function close_details() {
        document.getElementById('details').style.display = 'none';
      }

      class LineMatch {
        constructor(lineno, text) {
          this.lineno = lineno;
          this.text = text;
        }
      }

      class Analysis {
        constructor(filename, modules, line_matches) {
          this.filename = filename;
          this.modules = modules;
          this.line_matches = line_matches;
        }
      }

      class Module {
        constructor(deps) {
          this.deps = deps;
        }
      }

      function make_module_link(module) {
        var a = document.createElement('a');
        a.className = 'ModuleLink';
        a.innerText = module;
        a.href = '#module_' + module;
        return a;
      }

      function update_details(id) {
        document.getElementById('details').style.display = 'block';

        var analyses = ANALYSIS[id];

        var details = document.getElementById("details_data");
        while (details.firstChild) {
            details.removeChild(details.firstChild);
        }

        for (var i=0; i<analyses.length; i++) {
          var analysis = analyses[i];

          var makefileDiv = document.createElement('div');
          makefileDiv.className = 'Makefile';
          details.appendChild(makefileDiv);

          var fileA = document.createElement('a');
          makefileDiv.appendChild(fileA);
          fileA.className = 'CsLink';
          fileA.href = '%(codesearch)s' + analysis.filename;
          fileA.innerText = analysis.filename;
          fileA.target = "_blank";

          if (analysis.modules.length > 0) {
            var moduleTable = document.createElement('table');
            details.appendChild(moduleTable);

            for (var j=0; j<analysis.modules.length; j++) {
              var moduleRow = document.createElement('tr');
              moduleTable.appendChild(moduleRow);

              var moduleNameCell = document.createElement('td');
              moduleRow.appendChild(moduleNameCell);
              moduleNameCell.className = 'ModuleName';
              moduleNameCell.appendChild(make_module_link(analysis.modules[j]));

              var moduleData = MODULE_DATA[analysis.modules[j]];
              console.log(moduleData);

              var depCell = document.createElement('td');
              moduleRow.appendChild(depCell);

              if (moduleData.deps.length == 0) {
                depCell.className = 'ModuleDeps Unblocked';
                depCell.innerText = 'UNBLOCKED';
              } else {
                depCell.className = 'ModuleDeps Blocked';

                for (var k=0; k<moduleData.deps.length; k++) {
                  depCell.appendChild(make_module_link(moduleData.deps[k]));
                  depCell.appendChild(document.createElement('br'));
                }
              }
            }
          }

          if (analysis.line_matches.length > 0) {
            var lineTable = document.createElement('table');
            details.appendChild(lineTable);

            for (var j=0; j<analysis.line_matches.length; j++) {
              var line_match = analysis.line_matches[j];

              var lineRow = document.createElement('tr');
              lineTable.appendChild(lineRow);

              var linenoCell = document.createElement('td');
              lineRow.appendChild(linenoCell);
              linenoCell.className = 'LineNo';

              var linenoA = document.createElement('a');
              linenoCell.appendChild(linenoA);
              linenoA.className = 'CsLink';
              linenoA.href = '%(codesearch)s' + analysis.filename
                  + ';l=' + line_match.lineno;
              linenoA.innerText = line_match.lineno;
              linenoA.target = "_blank";

              var textCell = document.createElement('td');
              lineRow.appendChild(textCell);
              textCell.className = 'LineText';
              textCell.innerText = line_match.text;
            }
          }
        }
      }

      var ANALYSIS = [
      """ % {
          "codesearch": self.args.codesearch,
      })
    for entry, mods in self.annotations.entries:
      print("  [")
      for analysis in entry:
        print("    new Analysis('%(filename)s', %(modules)s, [%(line_matches)s])," % {
          "filename": analysis.filename,
          #"modules": json.dumps([m for m in mods if m in filename in self.soong.makefiles[m]]),
          "modules": json.dumps(
              [m for m in self.soong.reverse_makefiles[analysis.filename] if m in mods]),
          "line_matches": ", ".join([
              "new LineMatch(%d, %s)" % (lineno, json.dumps(text))
              for lineno, text in analysis.line_matches]),
        })
      print("  ],")
    print("""
      ];
      var MODULE_DATA = {
    """)
    for module in self.soong.modules:
      print("      '%(name)s': new Module(%(deps)s)," % {
        "name": module,
        "deps": json.dumps(self.soong.deps[module]),
      })
    print("""
      };
      </script>

    """)

    print("""
        </div> <!-- id=tables -->
        <div id="details">
          <div style="text-align: right;">
            <a href="javascript:close_details();">
              <svg xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 0 24 24" width="24"><path d="M0 0h24v24H0z" fill="none"/><path d="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"/></svg>
            </a>
          </div>
          <div id="details_data"></div>
        </div>
      </body>
    </html>
    """)

  def traverse_ready_makefiles(self, summary, makefiles):
    return [Analysis(makefile.filename, []) for makefile in makefiles
        if clean_and_only_blocked_by_clean(self.soong, self.all_makefiles, makefile)]

  def print_analysis_row(self, summary, modules, rowtitle, rowclass, makefiles):
    all_makefiles = [Analysis(makefile.filename, []) for makefile in makefiles]
    clean_makefiles = [Analysis(makefile.filename, []) for makefile in makefiles
        if is_clean(makefile)]
    easy_makefiles = self.traverse_ready_makefiles(summary, makefiles)
    unblocked_clean_makefiles = [Analysis(makefile.filename, []) for makefile in makefiles
        if (self.soong.contains_unblocked_modules(makefile.filename)
            and is_clean(makefile))]
    unblocked_makefiles = [Analysis(makefile.filename, []) for makefile in makefiles
        if self.soong.contains_unblocked_modules(makefile.filename)]
    blocked_makefiles = [Analysis(makefile.filename, []) for makefile in makefiles
        if self.soong.contains_blocked_modules(makefile.filename)]

    print("""
      <tr class="%(rowclass)s">
        <td class="RowTitle">%(rowtitle)s</td>
        <td class="Count">%(makefiles)s</td>
        <td class="Count">%(easy)s</td>
        <td class="Count">%(unblocked_clean)s</td>
        <td class="Count">%(unblocked)s</td>
        <td class="Count">%(blocked)s</td>
        <td class="Count">%(clean)s</td>
    """ % {
      "rowclass": rowclass,
      "rowtitle": rowtitle,
      "makefiles": self.make_annotation_link(all_makefiles, modules),
      "unblocked": self.make_annotation_link(unblocked_makefiles, modules),
      "blocked": self.make_annotation_link(blocked_makefiles, modules),
      "clean": self.make_annotation_link(clean_makefiles, modules),
      "unblocked_clean": self.make_annotation_link(unblocked_clean_makefiles, modules),
      "easy": self.make_annotation_link(easy_makefiles, modules),
    })

    for analyzer in ANALYZERS:
      analyses = [m.analyses.get(analyzer) for m in makefiles if m.analyses.get(analyzer)]
      print("""<td class="Count">%s</td>"""
          % self.make_annotation_link(analyses, modules))

    print("      </tr>")

  def make_annotation_link(self, analysis, modules):
    if analysis:
      return "<a href='javascript:update_details(%d)'>%s</a>" % (
        self.annotations.Add(analysis, modules),
        len(analysis)
      )
    else:
      return "";

class CsvProcessor(object):
  def __init__(self, args, soong, all_makefiles, product_packages_modules):
    self.args = args
    self.soong = soong
    self.all_makefiles = all_makefiles
    self.product_packages_modules = product_packages_modules

  def execute(self):
    csvout = csv.writer(sys.stdout)

    # Title row
    row = ["Filename", "Module", "Partitions", "Easy", "Unblocked Clean", "Unblocked",
           "Blocked", "Clean"]
    for analyzer in ANALYZERS:
      row.append(analyzer.title)
    csvout.writerow(row)

    # Makefile & module data
    for filename in sorted(self.all_makefiles.keys()):
      makefile = self.all_makefiles[filename]
      for module in self.soong.reverse_makefiles[filename]:
        if len(self.product_packages_modules) > 0 and module not in self.product_packages_modules:
          continue
        row = [filename, module]
        # Partitions
        row.append(";".join(sorted(set([get_partition_from_installed(HOST_OUT_ROOT, PRODUCT_OUT,
                                         installed)
                                        for installed
                                        in self.soong.reverse_installed.get(module, [])]))))
        # Easy
        row.append(1
            if clean_and_only_blocked_by_clean(self.soong, self.all_makefiles, makefile)
            else "")
        # Unblocked Clean
        row.append(1
            if (self.soong.contains_unblocked_modules(makefile.filename) and is_clean(makefile))
            else "")
        # Unblocked
        row.append(1 if self.soong.contains_unblocked_modules(makefile.filename) else "")
        # Blocked
        row.append(1 if self.soong.contains_blocked_modules(makefile.filename) else "")
        # Clean
        row.append(1 if is_clean(makefile) else "")
        # Analysis
        for analyzer in ANALYZERS:
          row.append(1 if makefile.analyses.get(analyzer) else "")
        # Write results
        csvout.writerow(row)

if __name__ == "__main__":
  main()

