// Copyright (c) 2023, 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.ir.desugar.desugaredlibrary.lint;

import com.android.tools.r8.graph.CfCode.LocalVariableInfo;
import com.android.tools.r8.graph.ClassAccessFlags;
import com.android.tools.r8.graph.DexEncodedField;
import com.android.tools.r8.graph.DexEncodedMethod;
import com.android.tools.r8.graph.DexProto;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.graph.FieldAccessFlags;
import com.android.tools.r8.graph.MethodAccessFlags;
import com.android.tools.r8.ir.desugar.desugaredlibrary.lint.SupportedClasses.ClassAnnotation;
import com.android.tools.r8.ir.desugar.desugaredlibrary.lint.SupportedClasses.FieldAnnotation;
import com.android.tools.r8.ir.desugar.desugaredlibrary.lint.SupportedClasses.MethodAnnotation;
import com.android.tools.r8.ir.desugar.desugaredlibrary.lint.SupportedClasses.SupportedClass;
import com.android.tools.r8.utils.AndroidApiLevel;
import com.android.tools.r8.utils.ListUtils;
import com.android.tools.r8.utils.StringUtils;
import java.io.PrintStream;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;

public class GenerateHtmlDoc extends AbstractGenerateFiles {

  private static final String HTML_SPLIT = "<br>&nbsp;";
  private static final int MAX_LINE_CHARACTERS = 53;
  private static final String SUP_1 = "<sup>1</sup>";
  private static final String SUP_2 = "<sup>2</sup>";
  private static final String SUP_3 = "<sup>3</sup>";
  private static final String SUP_4 = "<sup>4</sup>";

  public GenerateHtmlDoc(
      String desugarConfigurationPath, String desugarImplementationPath, String outputDirectory)
      throws Exception {
    super(desugarConfigurationPath, desugarImplementationPath, outputDirectory);
  }

  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 appendLineStart(String lineStart) {
      builder.append(indent);
      builder.append(lineStart);
      return this;
    }

    StringBuilderWithIndent append(String string) {
      builder.append(string);
      return this;
    }

    StringBuilderWithIndent appendLineEnd(String lineEnd) {
      builder.append(lineEnd);
      builder.append(NL);
      return this;
    }

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

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

  private abstract static class SourceBuilder<B extends GenerateHtmlDoc.SourceBuilder> {

    protected Map<DexEncodedField, FieldAnnotation> fields =
        new TreeMap<>(Comparator.comparing(DexEncodedField::getReference));
    protected Map<DexEncodedMethod, MethodAnnotation> constructors =
        new TreeMap<>(Comparator.comparing(DexEncodedMethod::getReference));
    protected Map<DexEncodedMethod, MethodAnnotation> methods =
        new TreeMap<>(Comparator.comparing(DexEncodedMethod::getReference));

    String className;
    String packageName;

    private SourceBuilder(DexType classType) {
      this.className = classType.toSourceString();
      int index = this.className.lastIndexOf('.');
      this.packageName = index > 0 ? this.className.substring(0, index) : "";
    }

    public abstract B self();

    private B addField(DexEncodedField field, FieldAnnotation fieldAnnotation) {
      fields.put(field, fieldAnnotation);
      return self();
    }

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

    // If we are in a.b.c, then anything starting with a.b should not be fully qualified.
    protected String typeInPackageRecursive(String typeName, String packageName) {
      String rewritten = typeInPackage(typeName, packageName);
      if (rewritten != null) {
        return rewritten;
      }
      List<String> split = StringUtils.split(packageName, '.');
      if (split.size() > 2) {
        String last = ListUtils.last(split);
        String prevPackage = packageName.substring(0, packageName.length() - last.length() - 1);
        return typeInPackage(typeName, prevPackage);
      }
      return null;
    }

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

    protected String typeInPackage(String typeName) {
      String result = typeInPackageRecursive(typeName, packageName);
      if (result == null) {
        result = typeInPackage(typeName, "java.lang");
      }
      if (result == null) {
        result = typeInPackage(typeName, "java.util.function");
      }
      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 appendTdPackage(String s) {
      String finalString = format(s, 4);
      appendLineStart("<td><code><em>" + finalString + "</em></code><br>");
      if (s.startsWith("java.time")) {
        append("<a href=\"#java-time-customizations\">See customizations</a><br");
      } else if (s.startsWith("java.nio")) {
        append("<a href=\"#java-nio-customizations\">See customizations</a><br");
      }
      return this;
    }

    private String format(String s, int i) {
      List<String> split = StringUtils.split(s, '.');
      if (split.size() < i) {
        return s;
      }
      int splitIndex = 0;
      int mid = i / 2;
      for (int j = 0; j < mid; j++) {
        splitIndex += split.get(j).length();
      }
      splitIndex += mid;
      return s.substring(0, splitIndex) + HTML_SPLIT + s.substring(splitIndex);
    }

    HTMLBuilder appendTdClassName(String s) {
      String finalString = format(s, 2);
      appendLineEnd(
          "<code><br><br><div style=\"font-size:small;font-weight:bold;\">&nbsp;"
              + finalString
              + "</div></code><br><br></td>");
      return this;
    }

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

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

    HTMLBuilder appendMethodLiCode(String s) {
      if (s.length() < MAX_LINE_CHARACTERS || s.contains("()")) {
        return appendLiCode(s);
      }
      StringBuilder sb = new StringBuilder();
      List<String> split = StringUtils.split(s, '(');
      sb.append(split.get(0)).append('(').append(HTML_SPLIT);
      if (split.get(1).length() < MAX_LINE_CHARACTERS - 2) {
        sb.append(split.get(1));
        return appendLiCode(sb.toString());
      }
      List<String> secondSplit = StringUtils.split(split.get(1), ',');
      sb.append("&nbsp;");
      for (int i = 0; i < secondSplit.size(); i++) {
        sb.append(secondSplit.get(i));
        if (i != secondSplit.size() - 1) {
          sb.append(',');
          sb.append(HTML_SPLIT);
        }
      }
      return appendLiCode(sb.toString());
    }

    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 ClassAnnotation classAnnotation;
    private boolean parallelStreamMethod = false;
    private boolean missingFromLatestAndroidJar = false;
    private boolean unsupportedInMinApiRange = false;
    private boolean covariantReturnSupported = false;

    public HTMLSourceBuilder(DexType classType, ClassAnnotation classAnnotation) {
      super(classType);
      this.classAnnotation = classAnnotation;
    }

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

    private String getTextAnnotations(FieldAnnotation annotation) {
      if (annotation == null) {
        return "";
      }
      StringBuilder stringBuilder = new StringBuilder();
      if (annotation.unsupportedInMinApiRange) {
        stringBuilder.append(SUP_3);
        unsupportedInMinApiRange = true;
      }
      return stringBuilder.toString();
    }

    private String getTextAnnotations(MethodAnnotation annotation) {
      if (annotation == null) {
        return "";
      }
      StringBuilder stringBuilder = new StringBuilder();
      if (annotation.parallelStreamMethod) {
        stringBuilder.append(SUP_1);
        parallelStreamMethod = true;
      }
      if (annotation.missingFromLatestAndroidJar) {
        stringBuilder.append(SUP_2);
        missingFromLatestAndroidJar = true;
      }
      if (annotation.unsupportedInMinApiRange) {
        stringBuilder.append(SUP_3);
        unsupportedInMinApiRange = true;
      }
      if (annotation.covariantReturnSupported) {
        stringBuilder.append(SUP_4);
        covariantReturnSupported = true;
      }
      return stringBuilder.toString();
    }

    @Override
    public String toString() {
      HTMLBuilder builder = new HTMLBuilder();
      builder.start("tr");
      if (packageName.length() > 0) {
        builder.appendTdPackage(packageName);
      }
      builder.appendTdClassName(typeInPackage(className));
      builder
          .start("td")
          .start(
              "ul style=\"list-style-position:inside; list-style-type: none !important;"
                  + " margin-left:0px;padding-left:0px !important;\"");
      if (!fields.isEmpty()) {
        for (DexEncodedField field : fields.keySet()) {
          builder.appendLiCode(
              accessFlags(field.accessFlags)
                  + " "
                  + typeInPackage(field.getReference().type)
                  + " "
                  + field.getReference().name
                  + getTextAnnotations(fields.get(field)));
        }
      }
      if (!constructors.isEmpty()) {
        for (DexEncodedMethod constructor : constructors.keySet()) {
          builder.appendMethodLiCode(
              accessFlags(constructor.accessFlags)
                  + " "
                  + typeInPackage(className)
                  + arguments(constructor)
                  + getTextAnnotations(constructors.get(constructor)));
        }
      }
      if (!methods.isEmpty()) {
        for (DexEncodedMethod method : methods.keySet()) {
          builder.appendMethodLiCode(
              accessFlags(method.accessFlags)
                  + " "
                  + typeInPackage(method.getReference().proto.returnType)
                  + " "
                  + method.getReference().name
                  + arguments(method)
                  + getTextAnnotations(methods.get(method)));
        }
      }
      builder.end("ul").end("td");
      StringBuilder commentBuilder = new StringBuilder();
      if (classAnnotation.isFullySupported()) {
        commentBuilder.append("Fully implemented class.").append(HTML_SPLIT);
      }
      if (classAnnotation.isAdditionalMembersOnClass()) {
        commentBuilder.append("Additional methods on existing class.").append(HTML_SPLIT);
      }
      if (parallelStreamMethod) {
        commentBuilder
            .append(SUP_1)
            .append(" Supported only on devices which API level is 21 or higher.")
            .append(HTML_SPLIT);
      }
      if (missingFromLatestAndroidJar) {
        commentBuilder
            .append(SUP_2)
            .append(" Not present in Android ")
            .append(MAX_TESTED_ANDROID_API_LEVEL)
            .append(" (May not resolve at compilation).")
            .append(HTML_SPLIT);
      }
      if (unsupportedInMinApiRange) {
        commentBuilder
            .append(SUP_3)
            .append(" Not supported at all minSDK levels.")
            .append(HTML_SPLIT);
      }
      if (covariantReturnSupported) {
        commentBuilder
            .append(SUP_4)
            .append(" Also supported with covariant return type.")
            .append(HTML_SPLIT);
      }
      if (!classAnnotation.getUnsupportedFields().isEmpty()) {
        commentBuilder
            .append("Some fields (")
            .append(classAnnotation.getUnsupportedFields().size())
            .append(") present in Android ")
            .append(MAX_TESTED_ANDROID_API_LEVEL)
            .append(" are not supported.")
            .append(HTML_SPLIT);
      }
      if (!classAnnotation.getUnsupportedMethods().isEmpty()) {
        commentBuilder
            .append("Some methods (")
            .append(classAnnotation.getUnsupportedMethods().size())
            .append(") present in Android ")
            .append(MAX_TESTED_ANDROID_API_LEVEL)
            .append(" are not supported.");
      }
      builder.appendTdP(commentBuilder.toString());
      builder.end("tr");
      return builder.toString();
    }
  }

  private void generateClassHTML(PrintStream ps, SupportedClass supportedClass) {
    DexType classType = supportedClass.getType();
    SourceBuilder<HTMLSourceBuilder> builder =
        new HTMLSourceBuilder(classType, supportedClass.getClassAnnotation());
    supportedClass.forEachFieldAndAnnotation(builder::addField);
    supportedClass.forEachMethodAndAnnotation(
        (method, methodAnnotation) -> {
          if (!method.accessFlags.isBridge()) {
            builder.addMethod(method, methodAnnotation);
          }
        });
    ps.println(builder);
  }

  @Override
  AndroidApiLevel run() throws Exception {
    return run("apis.html");
  }

  public AndroidApiLevel run(String outputFileName) throws Exception {
    PrintStream ps =
        new PrintStream(Files.newOutputStream(outputDirectory.resolve(outputFileName)));

    SupportedClasses supportedClasses =
        new SupportedClassesGenerator(options)
            .run(desugaredLibraryImplementation, desugaredLibrarySpecificationPath);

    // Full classes added.
    supportedClasses.forEachClass(supportedClass -> generateClassHTML(ps, supportedClass));
    return MAX_TESTED_ANDROID_API_LEVEL;
  }

  public static void main(String[] args) throws Exception {
    AbstractGenerateFiles.main(args);
  }
}
