// Copyright (c) 2019, the R8 project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

package com.android.tools.r8;

import com.android.tools.r8.cf.CfVersion;
import com.android.tools.r8.cf.code.CfConstNull;
import com.android.tools.r8.cf.code.CfInstruction;
import com.android.tools.r8.cf.code.CfThrow;
import com.android.tools.r8.dex.ApplicationReader;
import com.android.tools.r8.dex.Marker.Tool;
import com.android.tools.r8.graph.AppInfo;
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.CfCode;
import com.android.tools.r8.graph.CfCode.LocalVariableInfo;
import com.android.tools.r8.graph.ClassAccessFlags;
import com.android.tools.r8.graph.DexAnnotationSet;
import com.android.tools.r8.graph.DexApplication;
import com.android.tools.r8.graph.DexClass;
import com.android.tools.r8.graph.DexEncodedField;
import com.android.tools.r8.graph.DexEncodedMethod;
import com.android.tools.r8.graph.DexItemFactory;
import com.android.tools.r8.graph.DexMethod;
import com.android.tools.r8.graph.DexProgramClass;
import com.android.tools.r8.graph.DexProgramClass.ChecksumSupplier;
import com.android.tools.r8.graph.DexProto;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.graph.DirectMappedDexApplication;
import com.android.tools.r8.graph.FieldAccessFlags;
import com.android.tools.r8.graph.GenericSignature.ClassSignature;
import com.android.tools.r8.graph.GenericSignature.MethodTypeSignature;
import com.android.tools.r8.graph.LazyLoadedDexApplication;
import com.android.tools.r8.graph.MethodAccessFlags;
import com.android.tools.r8.graph.MethodCollection.MethodCollectionFactory;
import com.android.tools.r8.graph.ProgramMethod;
import com.android.tools.r8.ir.desugar.desugaredlibrary.DesugaredLibrarySpecification;
import com.android.tools.r8.ir.desugar.desugaredlibrary.DesugaredLibrarySpecificationParser;
import com.android.tools.r8.ir.desugar.desugaredlibrary.machinespecification.MachineDesugaredLibrarySpecification;
import com.android.tools.r8.jar.CfApplicationWriter;
import com.android.tools.r8.naming.NamingLens;
import com.android.tools.r8.origin.Origin;
import com.android.tools.r8.synthesis.SyntheticItems.GlobalSyntheticsStrategy;
import com.android.tools.r8.utils.AndroidApiLevel;
import com.android.tools.r8.utils.AndroidApp;
import com.android.tools.r8.utils.DescriptorUtils;
import com.android.tools.r8.utils.FileUtils;
import com.android.tools.r8.utils.InternalOptions;
import com.android.tools.r8.utils.Reporter;
import com.android.tools.r8.utils.StringUtils;
import com.android.tools.r8.utils.Timing;
import com.google.common.collect.Sets;
import java.io.File;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.function.BiPredicate;
import java.util.function.Predicate;
import java.util.stream.StreamSupport;

public class GenerateLintFiles {

  private static final String ANDROID_JAR_PATTERN = "third_party/android_jar/lib-v%d/android.jar";

  private final DexItemFactory factory = new DexItemFactory();
  private final Reporter reporter = new Reporter();
  private final InternalOptions options = new InternalOptions(factory, reporter);

  private final MachineDesugaredLibrarySpecification desugaredLibrarySpecification;
  private final Path desugaredLibraryImplementation;
  private final Path outputDirectory;

  private final Set<DexMethod> parallelMethods = Sets.newIdentityHashSet();

  public GenerateLintFiles(
      String desugarConfigurationPath, String desugarImplementationPath, String outputDirectory)
      throws Exception {
    DesugaredLibrarySpecification specification =
        readDesugaredLibraryConfiguration(desugarConfigurationPath);
    Path androidJarPath = getAndroidJarPath(specification.getRequiredCompilationApiLevel());
    this.desugaredLibrarySpecification =
        specification.toMachineSpecification(options, androidJarPath, Timing.empty());

    this.desugaredLibraryImplementation = Paths.get(desugarImplementationPath);
    this.outputDirectory = Paths.get(outputDirectory);
    if (!Files.isDirectory(this.outputDirectory)) {
      throw new Exception("Output directory " + outputDirectory + " is not a directory");
    }

    DexType streamType = factory.createType(factory.createString("Ljava/util/stream/Stream;"));
    DexMethod parallelMethod =
        factory.createMethod(
            factory.collectionType,
            factory.createProto(streamType),
            factory.createString("parallelStream"));
    parallelMethods.add(parallelMethod);
    DexType baseStreamType =
        factory.createType(factory.createString("Ljava/util/stream/BaseStream;"));
    for (String typePrefix : new String[] {"Base", "Double", "Int", "Long"}) {
      streamType =
          factory.createType(factory.createString("Ljava/util/stream/" + typePrefix + "Stream;"));
      parallelMethod =
          factory.createMethod(
              streamType, factory.createProto(streamType), factory.createString("parallel"));
      parallelMethods.add(parallelMethod);
      // Also filter out the generated bridges for the covariant return type.
      parallelMethod =
          factory.createMethod(
              streamType, factory.createProto(baseStreamType), factory.createString("parallel"));
      parallelMethods.add(parallelMethod);
    }
  }

  private static Path getAndroidJarPath(AndroidApiLevel apiLevel) {
    String jar = String.format(ANDROID_JAR_PATTERN, apiLevel.getLevel());
    return Paths.get(jar);
  }

  private DesugaredLibrarySpecification readDesugaredLibraryConfiguration(
      String desugarConfigurationPath) {
    return DesugaredLibrarySpecificationParser.parseDesugaredLibrarySpecification(
        StringResource.fromFile(Paths.get(desugarConfigurationPath)),
        factory,
        reporter,
        false,
        AndroidApiLevel.B.getLevel());
  }

  private CfCode buildEmptyThrowingCfCode(DexMethod method) {
    CfInstruction insn[] = {new CfConstNull(), new CfThrow()};
    return new CfCode(method.holder, 1, method.proto.parameters.size() + 1, Arrays.asList(insn));
  }

  private void addMethodsToHeaderJar(
      DexApplication.Builder builder, DexClass clazz, List<DexEncodedMethod> methods) {
    if (methods.size() == 0) {
      return;
    }

    List<DexEncodedMethod> directMethods = new ArrayList<>();
    List<DexEncodedMethod> virtualMethods = new ArrayList<>();
    for (DexEncodedMethod method : methods) {
      assert method.getHolderType() == clazz.type;
      CfCode code = null;
      if (!method.accessFlags.isAbstract() /*&& !method.accessFlags.isNative()*/) {
        code = buildEmptyThrowingCfCode(method.getReference());
      }
      DexEncodedMethod throwingMethod =
          DexEncodedMethod.builder()
              .setMethod(method.getReference())
              .setAccessFlags(method.accessFlags)
              .setGenericSignature(MethodTypeSignature.noSignature())
              .setCode(code)
              .setClassFileVersion(CfVersion.V1_6)
              .disableAndroidApiLevelCheck()
              .build();
      if (method.isStatic() || method.isDirectMethod()) {
        directMethods.add(throwingMethod);
      } else {
        virtualMethods.add(throwingMethod);
      }
    }

    DexEncodedMethod[] directMethodsArray = new DexEncodedMethod[directMethods.size()];
    DexEncodedMethod[] virtualMethodsArray = new DexEncodedMethod[virtualMethods.size()];
    directMethods.toArray(directMethodsArray);
    virtualMethods.toArray(virtualMethodsArray);
    assert !options.encodeChecksums;
    ChecksumSupplier checksumSupplier = DexProgramClass::invalidChecksumRequest;
    DexProgramClass programClass =
        new DexProgramClass(
            clazz.type,
            null,
            Origin.unknown(),
            clazz.accessFlags,
            clazz.superType,
            clazz.interfaces,
            null,
            null,
            Collections.emptyList(),
            null,
            Collections.emptyList(),
            ClassSignature.noSignature(),
            DexAnnotationSet.empty(),
            DexEncodedField.EMPTY_ARRAY,
            DexEncodedField.EMPTY_ARRAY,
            MethodCollectionFactory.fromMethods(directMethodsArray, virtualMethodsArray),
            false,
            checksumSupplier);
    builder.addProgramClass(programClass);
  }

  public static class SupportedMethods {

    public final Set<DexClass> classesWithAllMethodsSupported;
    public final Map<DexClass, List<DexEncodedMethod>> supportedMethods;

    public SupportedMethods(
        Set<DexClass> classesWithAllMethodsSupported,
        Map<DexClass, List<DexEncodedMethod>> supportedMethods) {
      this.classesWithAllMethodsSupported = classesWithAllMethodsSupported;
      this.supportedMethods = supportedMethods;
    }
  }

  private SupportedMethods collectSupportedMethods(
      AndroidApiLevel compilationApiLevel, Predicate<DexEncodedMethod> supported) throws Exception {

    // Read the android.jar for the compilation API level. Read it as program instead of library
    // to get the local information for parameter names.
    AndroidApp library =
        AndroidApp.builder().addProgramFiles(getAndroidJarPath(compilationApiLevel)).build();
    DirectMappedDexApplication dexApplication =
        new ApplicationReader(library, options, Timing.empty()).read().toDirect();

    AndroidApp implementation =
        AndroidApp.builder().addProgramFiles(desugaredLibraryImplementation).build();
    DirectMappedDexApplication implementationApplication =
        new ApplicationReader(implementation, options, Timing.empty()).read().toDirect();

    // Collect all the methods that the library desugar configuration adds support for.
    Set<DexClass> classesWithAllMethodsSupported = Sets.newIdentityHashSet();
    Map<DexClass, List<DexEncodedMethod>> supportedMethods = new LinkedHashMap<>();
    for (DexProgramClass clazz : dexApplication.classes()) {
      if (clazz.accessFlags.isPublic()
          && desugaredLibrarySpecification.getRewriteType().containsKey(clazz.type)) {
        DexProgramClass implementationClass =
            implementationApplication.programDefinitionFor(clazz.getType());
        if (implementationClass == null) {
          throw new Exception("Implementation class not found for " + clazz.toSourceString());
        }
        boolean allMethodsAdded = true;
        for (DexEncodedMethod method : clazz.methods()) {
          if (!method.isPublic()) {
            continue;
          }
          ProgramMethod implementationMethod =
              implementationClass.lookupProgramMethod(method.getReference());
          // Don't include methods which are not implemented by the desugared library.
          if (supported.test(method) && implementationMethod != null) {
            supportedMethods.computeIfAbsent(clazz, k -> new ArrayList<>()).add(method);
          } else {
            allMethodsAdded = false;
          }
        }
        if (allMethodsAdded) {
          classesWithAllMethodsSupported.add(clazz);
        }
      }

      // All emulated interfaces static and default methods are supported.
      if (desugaredLibrarySpecification.getEmulatedInterfaces().containsKey(clazz.type)) {
        assert clazz.isInterface();
        for (DexEncodedMethod method : clazz.methods()) {
          if (!method.isDefaultMethod() && !method.isStatic()) {
            continue;
          }
          if (supported.test(method)) {
            supportedMethods.computeIfAbsent(clazz, k -> new ArrayList<>()).add(method);
          }
        }
      }
    }

    // All retargeted methods are supported.
    desugaredLibrarySpecification.forEachRetargetMethod(
        method -> {
          DexClass clazz = dexApplication.contextIndependentDefinitionFor(method.getHolderType());
          assert clazz != null;
          DexEncodedMethod encodedMethod = clazz.lookupMethod(method);
          if (encodedMethod == null) {
            // Some methods are registered but present higher in the hierarchy, ignore them.
            return;
          }
          if (supported.test(encodedMethod)) {
            supportedMethods.computeIfAbsent(clazz, k -> new ArrayList<>()).add(encodedMethod);
          }
        });

    return new SupportedMethods(classesWithAllMethodsSupported, supportedMethods);
  }

  private String lintBaseFileName(
      AndroidApiLevel compilationApiLevel, AndroidApiLevel minApiLevel) {
    return "desugared_apis_" + compilationApiLevel.getLevel() + "_" + minApiLevel.getLevel();
  }

  private Path lintFile(
      AndroidApiLevel compilationApiLevel, AndroidApiLevel minApiLevel, String extension)
      throws Exception {
    Path directory = outputDirectory.resolve("compile_api_level_" + compilationApiLevel.getLevel());
    Files.createDirectories(directory);
    return Paths.get(
        directory
            + File.separator
            + lintBaseFileName(compilationApiLevel, minApiLevel)
            + extension);
  }

  private void writeLintFiles(
      AndroidApiLevel compilationApiLevel,
      AndroidApiLevel minApiLevel,
      SupportedMethods supportedMethods)
      throws Exception {
    // Build a plain text file with the desugared APIs.
    List<String> desugaredApisSignatures = new ArrayList<>();

    LazyLoadedDexApplication.Builder builder = DexApplication.builder(options, Timing.empty());
    supportedMethods.supportedMethods.forEach(
        (clazz, methods) -> {
          String classBinaryName =
              DescriptorUtils.getClassBinaryNameFromDescriptor(clazz.type.descriptor.toString());
          if (!supportedMethods.classesWithAllMethodsSupported.contains(clazz)) {
            for (DexEncodedMethod method : methods) {
              if (method.isInstanceInitializer() || method.isClassInitializer()) {
                // No new constructors are added.
                continue;
              }
              desugaredApisSignatures.add(
                  classBinaryName
                      + '#'
                      + method.getReference().name
                      + method.getReference().proto.toDescriptorString());
            }
          } else {
            desugaredApisSignatures.add(classBinaryName);
          }

          addMethodsToHeaderJar(builder, clazz, methods);
        });

    // Write a plain text file with the desugared APIs.
    desugaredApisSignatures.sort(Comparator.naturalOrder());
    FileUtils.writeTextFile(
        lintFile(compilationApiLevel, minApiLevel, ".txt"), desugaredApisSignatures);

    // Write a header jar with the desugared APIs.
    AppView<?> appView =
        AppView.createForD8(
            AppInfo.createInitialAppInfo(
                builder.build(), GlobalSyntheticsStrategy.forNonSynthesizing()));
    CfApplicationWriter writer =
        new CfApplicationWriter(
            appView,
            options.getMarker(Tool.L8),
            NamingLens.getIdentityLens());
    ClassFileConsumer consumer =
        new ClassFileConsumer.ArchiveConsumer(
            lintFile(compilationApiLevel, minApiLevel, FileUtils.JAR_EXTENSION));
    writer.write(consumer);
    consumer.finished(options.reporter);
  }

  private void generateLintFiles(
      AndroidApiLevel compilationApiLevel,
      Predicate<AndroidApiLevel> generateForThisMinApiLevel,
      BiPredicate<AndroidApiLevel, DexEncodedMethod> supportedForMinApiLevel)
      throws Exception {
    System.out.print("  - generating for min API:");
    for (AndroidApiLevel minApiLevel : AndroidApiLevel.values()) {
      if (!generateForThisMinApiLevel.test(minApiLevel)) {
        continue;
      }

      System.out.print(" " + minApiLevel);

      SupportedMethods supportedMethods =
          collectSupportedMethods(
              compilationApiLevel, (method -> supportedForMinApiLevel.test(minApiLevel, method)));
      writeLintFiles(compilationApiLevel, minApiLevel, supportedMethods);
    }
    System.out.println();
  }

  private void run() throws Exception {
    // Run over all the API levels that the desugared library can be compiled with.
    for (int apiLevel = AndroidApiLevel.Sv2.getLevel();
        apiLevel >= desugaredLibrarySpecification.getRequiredCompilationApiLevel().getLevel();
        apiLevel--) {
      System.out.println("Generating lint files for compile API " + apiLevel);
      run(apiLevel);
    }
  }

  public void run(int apiLevel) throws Exception {
    generateLintFiles(
        AndroidApiLevel.getAndroidApiLevel(apiLevel),
        minApiLevel -> minApiLevel == AndroidApiLevel.L || minApiLevel == AndroidApiLevel.B,
        (minApiLevel, method) -> {
          assert minApiLevel == AndroidApiLevel.L || minApiLevel == AndroidApiLevel.B;
          if (minApiLevel == AndroidApiLevel.L) {
            return true;
          }
          assert minApiLevel == AndroidApiLevel.B;
          return !parallelMethods.contains(method.getReference());
        });
  }

  private static class StringBuilderWithIndent {

    String NL = System.lineSeparator();
    StringBuilder builder = new StringBuilder();
    String indent = "";

    StringBuilderWithIndent() {}

    StringBuilderWithIndent indent(String indent) {
      this.indent = indent;
      return this;
    }

    StringBuilderWithIndent appendLine(String line) {
      builder.append(indent);
      builder.append(line);
      builder.append(NL);
      return this;
    }

    StringBuilderWithIndent emptyLine() {
      builder.append(NL);
      return this;
    }

    @Override
    public String toString() {
      return builder.toString();
    }
  }

  private abstract static class SourceBuilder<B extends SourceBuilder> {

    protected final DexClass clazz;
    protected final boolean newClass;
    protected List<DexEncodedField> fields = new ArrayList<>();
    protected List<DexEncodedMethod> constructors = new ArrayList<>();
    protected List<DexEncodedMethod> methods = new ArrayList<>();

    String className;
    String packageName;

    private SourceBuilder(DexClass clazz, boolean newClass) {
      this.clazz = clazz;
      this.newClass = newClass;
      this.className = clazz.type.toSourceString();
      int index = this.className.lastIndexOf('.');
      this.packageName = index > 0 ? this.className.substring(0, index) : "";
    }

    public abstract B self();

    private B addField(DexEncodedField field) {
      fields.add(field);
      return self();
    }

    private B addMethod(DexEncodedMethod method) {
      assert !method.isClassInitializer();
      if (method.isInitializer()) {
        constructors.add(method);
      } else {
        methods.add(method);
      }
      return self();
    }

    protected String typeInPackage(String typeName, String packageName) {
      if (typeName.startsWith(packageName)
          && typeName.length() > packageName.length()
          && typeName.charAt(packageName.length()) == '.'
          && typeName.indexOf('.', packageName.length() + 1) == -1) {
        return typeName.substring(packageName.length() + 1);
      }
      return null;
    }

    protected String typeInPackage(String typeName) {
      String result = typeInPackage(typeName, packageName);
      if (result == null) {
        result = typeInPackage(typeName, "java.lang");
      }
      if (result == null) {
        result = typeName;
      }
      return result.replace('$', '.');
    }

    protected String typeInPackage(DexType type) {
      if (type.isPrimitiveType()) {
        return type.toSourceString();
      }
      return typeInPackage(type.toSourceString());
    }

    protected String accessFlags(ClassAccessFlags accessFlags) {
      List<String> flags = new ArrayList<>();
      if (accessFlags.isPublic()) {
        flags.add("public");
      }
      if (accessFlags.isProtected()) {
        flags.add("protected");
      }
      if (accessFlags.isPrivate()) {
        assert false;
        flags.add("private");
      }
      if (accessFlags.isPackagePrivate()) {
        assert false;
        flags.add("/* package */");
      }
      if (accessFlags.isAbstract() && !accessFlags.isInterface()) {
        flags.add("abstract");
      }
      if (accessFlags.isStatic()) {
        flags.add("static");
      }
      if (accessFlags.isFinal()) {
        flags.add("final");
      }
      return String.join(" ", flags);
    }

    protected String accessFlags(FieldAccessFlags accessFlags) {
      List<String> flags = new ArrayList<>();
      if (accessFlags.isPublic()) {
        flags.add("public");
      }
      if (accessFlags.isProtected()) {
        flags.add("protected");
      }
      if (accessFlags.isPrivate()) {
        assert false;
        flags.add("private");
      }
      if (accessFlags.isPackagePrivate()) {
        assert false;
        flags.add("/* package */");
      }
      if (accessFlags.isStatic()) {
        flags.add("static");
      }
      if (accessFlags.isFinal()) {
        flags.add("final");
      }
      return String.join(" ", flags);
    }

    protected String accessFlags(MethodAccessFlags accessFlags) {
      List<String> flags = new ArrayList<>();
      if (accessFlags.isPublic()) {
        flags.add("public");
      }
      if (accessFlags.isProtected()) {
        flags.add("protected");
      }
      if (accessFlags.isPrivate()) {
        assert false;
        flags.add("private");
      }
      if (accessFlags.isPackagePrivate()) {
        assert false;
        flags.add("/* package */");
      }
      if (accessFlags.isAbstract()) {
        flags.add("abstract");
      }
      if (accessFlags.isStatic()) {
        flags.add("static");
      }
      if (accessFlags.isFinal()) {
        flags.add("final");
      }
      return String.join(" ", flags);
    }

    public String arguments(DexEncodedMethod method) {
      DexProto proto = method.getReference().proto;
      StringBuilder argsBuilder = new StringBuilder();
      boolean firstArg = true;
      int argIndex = method.isVirtualMethod() || method.accessFlags.isConstructor() ? 1 : 0;
      int argNumber = 0;
      argsBuilder.append("(");
      for (DexType type : proto.parameters.values) {
        if (!firstArg) {
          argsBuilder.append(", ");
        }
        if (method.hasCode()) {
          String name = "p" + argNumber;
          for (LocalVariableInfo localVariable : method.getCode().asCfCode().getLocalVariables()) {
            if (localVariable.getIndex() == argIndex) {
              assert !localVariable.getLocal().name.toString().equals("this");
              name = localVariable.getLocal().name.toString();
            }
          }
          argsBuilder.append(typeInPackage(type)).append(" ").append(name);
        } else {
          argsBuilder.append(typeInPackage(type)).append(" p").append(argNumber);
        }
        firstArg = false;
        argIndex += type.isWideType() ? 2 : 1;
        argNumber++;
      }
      argsBuilder.append(")");
      return argsBuilder.toString();
    }
  }

  private static class HTMLBuilder extends StringBuilderWithIndent {

    private String indent = "";

    private void increaseIndent() {
      indent += "  ";
      indent(indent);
    }

    private void decreaseIndent() {
      indent = indent.substring(0, indent.length() - 2);
      indent(indent);
    }

    HTMLBuilder appendTdCode(String s) {
      appendLine("<td><code>" + s + "</code></td>");
      return this;
    }

    HTMLBuilder appendTdP(String s) {
      appendLine("<td><p>" + s + "</p></td>");
      return this;
    }

    HTMLBuilder appendLiCode(String s) {
      appendLine("<li><code>" + s + "</code></li>");
      return this;
    }

    HTMLBuilder start(String tag) {
      appendLine("<" + tag + ">");
      increaseIndent();
      return this;
    }

    HTMLBuilder end(String tag) {
      decreaseIndent();
      appendLine("</" + tag + ">");
      return this;
    }
  }

  public static class HTMLSourceBuilder extends SourceBuilder<HTMLSourceBuilder> {

    private final Set<DexMethod> parallelMethods;

    public HTMLSourceBuilder(DexClass clazz, boolean newClass, Set<DexMethod> parallelMethods) {
      super(clazz, newClass);
      this.parallelMethods = parallelMethods;
    }

    @Override
    public HTMLSourceBuilder self() {
      return this;
    }

    @Override
    public String toString() {
      HTMLBuilder builder = new HTMLBuilder();
      builder.start("tr");
      if (packageName.length() > 0) {
        builder.appendTdCode(packageName);
      }
      builder.appendTdCode(typeInPackage(className));
      builder.start("td").start("ul");
      if (!fields.isEmpty()) {
        assert newClass; // Currently no fields are added to existing classes.
        for (DexEncodedField field : fields) {
          builder.appendLiCode(
              accessFlags(field.accessFlags)
                  + " "
                  + typeInPackage(field.getReference().type)
                  + " "
                  + field.getReference().name);
        }
      }
      if (!constructors.isEmpty()) {
        for (DexEncodedMethod constructor : constructors) {
          builder.appendLiCode(
              accessFlags(constructor.accessFlags)
                  + " "
                  + typeInPackage(className)
                  + arguments(constructor));
        }
      }
      List<String> parallelM = new ArrayList<>();
      if (!methods.isEmpty()) {
        for (DexEncodedMethod method : methods) {
          builder.appendLiCode(
              accessFlags(method.accessFlags)
                  + " "
                  + typeInPackage(method.getReference().proto.returnType)
                  + " "
                  + method.getReference().name
                  + arguments(method));
          if (parallelMethods.contains(method.getReference())) {
            parallelM.add(method.getReference().name.toString());
          }
        }
      }
      builder.end("ul").end("td");
      StringBuilder commentBuilder = new StringBuilder();
      if (newClass) {
        commentBuilder.append("Fully implemented class.");
      } else {
        commentBuilder.append("Additional methods on existing class.");
      }
      if (!parallelM.isEmpty()) {
        commentBuilder.append(newClass ? "" : "<br>");
        if (parallelM.size() == 1) {
          commentBuilder
              .append("The method <code>")
              .append(parallelM.get(0))
              .append("</code> is only supported from API level 21.");
        } else {
          commentBuilder.append("The following methods are only supported from API level 21:<br>");
          for (int i = 0; i < parallelM.size(); i++) {
            commentBuilder.append("<code>").append(parallelM.get(i)).append("</code><br>");
          }
        }
      }
      builder.appendTdP(commentBuilder.toString());
      builder.end("tr");
      return builder.toString();
    }
  }

  private void generateClassHTML(
      PrintStream ps,
      DexClass clazz,
      boolean newClass,
      Predicate<DexEncodedField> fieldsFilter,
      Predicate<DexEncodedMethod> methodsFilter) {
    SourceBuilder builder = new HTMLSourceBuilder(clazz, newClass, parallelMethods);
    StreamSupport.stream(clazz.fields().spliterator(), false)
        .filter(fieldsFilter)
        .filter(field -> field.accessFlags.isPublic() || field.accessFlags.isProtected())
        .sorted(Comparator.comparing(DexEncodedField::toSourceString))
        .forEach(builder::addField);
    StreamSupport.stream(clazz.methods().spliterator(), false)
        .filter(methodsFilter)
        .filter(
            method ->
                (method.accessFlags.isPublic() || method.accessFlags.isProtected())
                    && !method.accessFlags.isBridge())
        .sorted(Comparator.comparing(DexEncodedMethod::toSourceString))
        .forEach(builder::addMethod);
    ps.println(builder);
  }

  private void generateDesugaredLibraryApisDocumetation() throws Exception {
    PrintStream ps = new PrintStream(Files.newOutputStream(outputDirectory.resolve("apis.html")));
    // Full classes added.
    SupportedMethods supportedMethods = collectSupportedMethods(AndroidApiLevel.Q, x -> true);
    supportedMethods.classesWithAllMethodsSupported.stream()
        .sorted(Comparator.comparing(clazz -> clazz.type.toSourceString()))
        .forEach(clazz -> generateClassHTML(ps, clazz, true, field -> true, method -> true));

    // Methods added to existing classes.
    supportedMethods.supportedMethods.keySet().stream()
        .filter(clazz -> !supportedMethods.classesWithAllMethodsSupported.contains(clazz))
        .sorted(Comparator.comparing(clazz -> clazz.type.toSourceString()))
        .forEach(
            clazz ->
                generateClassHTML(
                    ps,
                    clazz,
                    false,
                    field -> false,
                    method -> supportedMethods.supportedMethods.get(clazz).contains(method)));
  }

  public static void main(String[] args) throws Exception {
    if (args.length == 3) {
      new GenerateLintFiles(args[0], args[1], args[2]).run();
      return;
    }
    if (args.length == 4 && args[0].equals("--generate-api-docs")) {
      new GenerateLintFiles(args[1], args[2], args[3]).generateDesugaredLibraryApisDocumetation();
      return;
    }
    throw new RuntimeException(
        StringUtils.joinLines(
            "Invalid invocation.",
            "Usage: GenerateLineFiles [--generate-api-docs] "
                + "<desugar configuration> <desugar implementation> <output directory>"));
  }
}
