// Copyright (c) 2021, 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.apimodel;

import com.android.tools.r8.TestBase;
import com.android.tools.r8.androidapi.AndroidApiLevelHashingDatabaseImpl;
import com.android.tools.r8.apimodel.AndroidApiVersionsXmlParser.ParsedApiClass;
import com.android.tools.r8.graph.DexField;
import com.android.tools.r8.graph.DexItemFactory;
import com.android.tools.r8.graph.DexMember;
import com.android.tools.r8.graph.DexMethod;
import com.android.tools.r8.graph.DexReference;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.references.ClassReference;
import com.android.tools.r8.utils.AndroidApiLevel;
import com.android.tools.r8.utils.Pair;
import com.android.tools.r8.utils.structural.DefaultHashingVisitor;
import com.android.tools.r8.utils.structural.HasherWrapper;
import com.android.tools.r8.utils.structural.StructuralItem;
import java.io.FileOutputStream;
import java.io.ObjectOutputStream;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.IdentityHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.function.BiConsumer;

public class AndroidApiHashingDatabaseBuilderGenerator extends TestBase {

  /**
   * Generate the information needed for looking up api level of references in the android.jar. This
   * method will generate three different files and store them in the passed paths. pathToIndices
   * will be an int array with hashcode entries for each DexReference. The pathToApiLevels is a byte
   * array with a byte describing the api level that the index in pathToIndices has. To ensure that
   * this lookup work the generate algorithm tracks all colliding hash codes such and stores them in
   * another format. The indices map is populated with all colliding entries and a -1 is inserted
   * for the api level.
   */
  public static void generate(
      List<ParsedApiClass> apiClasses,
      Path pathToIndices,
      Path pathToApiLevels,
      Path ambiguousDefinitions)
      throws Exception {
    Map<ClassReference, Map<DexMethod, AndroidApiLevel>> methodMap = new HashMap<>();
    Map<ClassReference, Map<DexField, AndroidApiLevel>> fieldMap = new HashMap<>();
    Map<ClassReference, ParsedApiClass> lookupMap = new HashMap<>();
    DexItemFactory factory = new DexItemFactory();

    Map<Integer, AndroidApiLevel> apiLevelMap = new HashMap<>();
    Map<Integer, Pair<DexReference, AndroidApiLevel>> reverseMap = new HashMap<>();
    Map<AndroidApiLevel, Set<DexReference>> ambiguousMap = new HashMap<>();
    // Populate maps for faster lookup.
    for (ParsedApiClass apiClass : apiClasses) {
      DexType type = factory.createType(apiClass.getClassReference().getDescriptor());
      AndroidApiLevel existing = apiLevelMap.put(type.hashCode(), apiClass.getApiLevel());
      assert existing == null;
      reverseMap.put(type.hashCode(), Pair.create(type, apiClass.getApiLevel()));
    }

    for (ParsedApiClass apiClass : apiClasses) {
      Map<DexMethod, AndroidApiLevel> methodsForApiClass = new HashMap<>();
      apiClass.visitMethodReferences(
          (apiLevel, methods) -> {
            methods.forEach(
                method -> methodsForApiClass.put(factory.createMethod(method), apiLevel));
          });
      Map<DexField, AndroidApiLevel> fieldsForApiClass = new HashMap<>();
      apiClass.visitFieldReferences(
          (apiLevel, fields) -> {
            fields.forEach(field -> fieldsForApiClass.put(factory.createField(field), apiLevel));
          });
      methodMap.put(apiClass.getClassReference(), methodsForApiClass);
      fieldMap.put(apiClass.getClassReference(), fieldsForApiClass);
      lookupMap.put(apiClass.getClassReference(), apiClass);
    }

    BiConsumer<DexReference, AndroidApiLevel> addConsumer =
        addReferenceToMaps(apiLevelMap, reverseMap, ambiguousMap);

    for (ParsedApiClass apiClass : apiClasses) {
      computeAllReferencesInHierarchy(
              lookupMap,
              factory,
              factory.createType(apiClass.getClassReference().getDescriptor()),
              apiClass,
              AndroidApiLevel.B,
              new IdentityHashMap<>())
          .forEach(addConsumer);
    }

    int[] indices = new int[apiLevelMap.size()];
    byte[] apiLevel = new byte[apiLevelMap.size()];
    ArrayList<Integer> integers = new ArrayList<>(apiLevelMap.keySet());
    for (int i = 0; i < integers.size(); i++) {
      indices[i] = integers.get(i);
      AndroidApiLevel androidApiLevel = apiLevelMap.get(integers.get(i));
      apiLevel[i] = (byte) (androidApiLevel == null ? -1 : androidApiLevel.getLevel());
    }

    try (FileOutputStream fileOutputStream = new FileOutputStream(pathToIndices.toFile());
        ObjectOutputStream objectOutputStream = new ObjectOutputStream(fileOutputStream)) {
      objectOutputStream.writeObject(indices);
    }

    try (FileOutputStream fileOutputStream = new FileOutputStream(pathToApiLevels.toFile());
        ObjectOutputStream objectOutputStream = new ObjectOutputStream(fileOutputStream)) {
      objectOutputStream.writeObject(apiLevel);
    }

    String ambiguousMapSerialized = serializeAmbiguousMap(ambiguousMap);
    Files.write(ambiguousDefinitions, ambiguousMapSerialized.getBytes(StandardCharsets.UTF_8));
  }

  /** This will serialize a collection of DexReferences with the api level they correspond to. */
  private static String serializeAmbiguousMap(
      Map<AndroidApiLevel, Set<DexReference>> ambiguousMap) {
    Set<String> seen = new HashSet<>();
    StringBuilder sb = new StringBuilder();
    ambiguousMap.forEach(
        (apiLevel, references) -> {
          references.forEach(
              reference -> {
                HasherWrapper defaultHasher = AndroidApiLevelHashingDatabaseImpl.getDefaultHasher();
                reference.accept(
                    type -> DefaultHashingVisitor.run(type, defaultHasher, DexType::acceptHashing),
                    field ->
                        DefaultHashingVisitor.run(
                            field, defaultHasher, StructuralItem::acceptHashing),
                    method ->
                        DefaultHashingVisitor.run(
                            method, defaultHasher, StructuralItem::acceptHashing));
                String referenceHash = defaultHasher.hash().toString();
                if (!seen.add(referenceHash)) {
                  throw new RuntimeException(
                      "More than one item with key: <"
                          + referenceHash
                          + ">. The choice of key encoding will need to change to generate a valid"
                          + " api database");
                }
                sb.append(referenceHash).append(":").append(apiLevel.getLevel()).append("\n");
              });
        });
    return sb.toString();
  }

  private static BiConsumer<DexReference, AndroidApiLevel> addReferenceToMaps(
      Map<Integer, AndroidApiLevel> apiLevelMap,
      Map<Integer, Pair<DexReference, AndroidApiLevel>> reverseMap,
      Map<AndroidApiLevel, Set<DexReference>> ambiguousMap) {
    return ((reference, apiLevel) -> {
      AndroidApiLevel existingMethod = apiLevelMap.put(reference.hashCode(), apiLevel);
      if (existingMethod != null) {
        apiLevelMap.put(reference.hashCode(), null);
        Pair<DexReference, AndroidApiLevel> existingPair = reverseMap.get(reference.hashCode());
        addAmbiguousEntry(existingPair.getSecond(), existingPair.getFirst(), ambiguousMap);
        addAmbiguousEntry(apiLevel, reference, ambiguousMap);
      } else {
        reverseMap.put(reference.hashCode(), Pair.create(reference, apiLevel));
      }
    });
  }

  private static void addAmbiguousEntry(
      AndroidApiLevel apiLevel,
      DexReference reference,
      Map<AndroidApiLevel, Set<DexReference>> ambiguousMap) {
    ambiguousMap.computeIfAbsent(apiLevel, ignored -> new HashSet<>()).add(reference);
  }

  @SuppressWarnings("unchecked")
  private static <T extends DexMember<?, ?>>
      Map<T, AndroidApiLevel> computeAllReferencesInHierarchy(
          Map<ClassReference, ParsedApiClass> lookupMap,
          DexItemFactory factory,
          DexType holder,
          ParsedApiClass apiClass,
          AndroidApiLevel linkLevel,
          Map<T, AndroidApiLevel> additionMap) {
    if (!apiClass.getClassReference().getDescriptor().equals(factory.objectDescriptor.toString())) {
      apiClass.visitMethodReferences(
          (apiLevel, methodReferences) -> {
            methodReferences.forEach(
                methodReference -> {
                  T member = (T) factory.createMethod(methodReference).withHolder(holder, factory);
                  addIfNewOrApiLevelIsLower(linkLevel, additionMap, apiLevel, member);
                });
          });
      apiClass.visitFieldReferences(
          (apiLevel, fieldReferences) -> {
            fieldReferences.forEach(
                fieldReference -> {
                  T member = (T) factory.createField(fieldReference).withHolder(holder, factory);
                  addIfNewOrApiLevelIsLower(linkLevel, additionMap, apiLevel, member);
                });
          });
      apiClass.visitSuperType(
          (superType, apiLevel) -> {
            computeAllReferencesInHierarchy(
                lookupMap,
                factory,
                holder,
                lookupMap.get(superType),
                linkLevel.max(apiLevel),
                additionMap);
          });
      apiClass.visitInterface(
          (iFace, apiLevel) -> {
            computeAllReferencesInHierarchy(
                lookupMap,
                factory,
                holder,
                lookupMap.get(iFace),
                linkLevel.max(apiLevel),
                additionMap);
          });
    }
    return additionMap;
  }

  private static <T extends DexMember<?, ?>> void addIfNewOrApiLevelIsLower(
      AndroidApiLevel linkLevel,
      Map<T, AndroidApiLevel> additionMap,
      AndroidApiLevel apiLevel,
      T member) {
    AndroidApiLevel currentApiLevel = apiLevel.max(linkLevel);
    AndroidApiLevel existingApiLevel = additionMap.get(member);
    if (existingApiLevel == null || currentApiLevel.isLessThanOrEqualTo(existingApiLevel)) {
      additionMap.put(member, currentApiLevel);
    }
  }
}
