// 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.androidapi;

import static com.android.tools.r8.lightir.ByteUtils.isU2;
import static com.android.tools.r8.utils.AndroidApiLevel.ANDROID_PLATFORM;

import com.android.tools.r8.DiagnosticsHandler;
import com.android.tools.r8.graph.DexField;
import com.android.tools.r8.graph.DexMethod;
import com.android.tools.r8.graph.DexReference;
import com.android.tools.r8.graph.DexString;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.utils.AndroidApiLevel;
import com.android.tools.r8.utils.InternalOptions;
import com.android.tools.r8.utils.ThrowingFunction;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

public class AndroidApiLevelHashingDatabaseImpl implements AndroidApiLevelDatabase {

  private static final byte TYPE_IDENTIFIER = 0;
  private static final byte FIELD_IDENTIFIER = 1;
  private static final byte METHOD_IDENTIFIER = 2;

  private static final byte[] NON_EXISTING_DESCRIPTOR = new byte[0];

  public static byte[] getNonExistingDescriptor() {
    return NON_EXISTING_DESCRIPTOR;
  }

  public static byte[] getUniqueDescriptorForReference(
      DexReference reference, ThrowingFunction<DexString, Integer, IOException> constantPoolLookup)
      throws IOException {
    if (reference.isDexType()) {
      return typeToBytes(constantPoolLookup.apply(reference.asDexType().getDescriptor()));
    }
    int holderId =
        constantPoolLookup.apply(reference.asDexMember().getHolderType().getDescriptor());
    if (holderId < 0) {
      return NON_EXISTING_DESCRIPTOR;
    }
    int nameId = constantPoolLookup.apply(reference.asDexMember().getName());
    if (nameId < 0) {
      return NON_EXISTING_DESCRIPTOR;
    }
    if (reference.isDexField()) {
      return fieldToBytes(
          holderId,
          nameId,
          constantPoolLookup.apply(reference.asDexField().getType().getDescriptor()));
    }
    assert reference.isDexMethod();
    return methodToBytes(holderId, nameId, reference.asDexMethod(), constantPoolLookup);
  }

  private static byte[] typeToBytes(int typeId) {
    if (typeId < 0) {
      return NON_EXISTING_DESCRIPTOR;
    }
    return new byte[] {
      TYPE_IDENTIFIER, getFirstByteFromShort(typeId), getSecondByteFromShort(typeId)
    };
  }

  private static byte[] fieldToBytes(int holderId, int nameId, int typeId) {
    if (holderId < 0 || nameId < 0 || typeId < 0) {
      return NON_EXISTING_DESCRIPTOR;
    }
    return new byte[] {
      FIELD_IDENTIFIER,
      getFirstByteFromShort(holderId),
      getSecondByteFromShort(holderId),
      getFirstByteFromShort(nameId),
      getSecondByteFromShort(nameId),
      getFirstByteFromShort(typeId),
      getSecondByteFromShort(typeId)
    };
  }

  private static byte[] methodToBytes(
      int holderId,
      int nameId,
      DexMethod method,
      ThrowingFunction<DexString, Integer, IOException> constantPoolLookup)
      throws IOException {
    if (holderId < 0 || nameId < 0) {
      return NON_EXISTING_DESCRIPTOR;
    }
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    baos.write(METHOD_IDENTIFIER);
    baos.write(getFirstByteFromShort(holderId));
    baos.write(getSecondByteFromShort(holderId));
    baos.write(getFirstByteFromShort(nameId));
    baos.write(getSecondByteFromShort(nameId));
    for (DexType parameter : method.proto.parameters) {
      int parameterId = constantPoolLookup.apply(parameter.getDescriptor());
      if (parameterId < 0) {
        return NON_EXISTING_DESCRIPTOR;
      }
      baos.write(getFirstByteFromShort(parameterId));
      baos.write(getSecondByteFromShort(parameterId));
    }
    int returnTypeId = constantPoolLookup.apply(method.getReturnType().getDescriptor());
    if (returnTypeId < 0) {
      return NON_EXISTING_DESCRIPTOR;
    }
    baos.write(getFirstByteFromShort(returnTypeId));
    baos.write(getSecondByteFromShort(returnTypeId));
    return baos.toByteArray();
  }

  private static byte getFirstByteFromShort(int value) {
    assert isU2(value);
    return (byte) (value >> 8);
  }

  private static byte getSecondByteFromShort(int value) {
    assert isU2(value);
    return (byte) value;
  }

  private final Map<DexReference, AndroidApiLevel> lookupCache = new ConcurrentHashMap<>();
  private final Map<DexString, Integer> constantPoolCache = new ConcurrentHashMap<>();
  private final InternalOptions options;
  private final DiagnosticsHandler diagnosticsHandler;
  private static volatile AndroidApiDataAccess dataAccess;

  private static AndroidApiDataAccess getDataAccess(
      InternalOptions options, DiagnosticsHandler diagnosticsHandler) {
    if (dataAccess == null) {
      synchronized (AndroidApiDataAccess.class) {
        if (dataAccess == null) {
          dataAccess = AndroidApiDataAccess.create(options, diagnosticsHandler);
        }
      }
    }
    return dataAccess;
  }

  public AndroidApiLevelHashingDatabaseImpl(
      List<AndroidApiForHashingReference> predefinedApiTypeLookup,
      InternalOptions options,
      DiagnosticsHandler diagnosticsHandler) {
    this.options = options;
    this.diagnosticsHandler = diagnosticsHandler;
    predefinedApiTypeLookup.forEach(
        predefinedApiReference -> {
          // Do not use computeIfAbsent since a return value of null implies the key should not be
          // inserted.
          lookupCache.put(
              predefinedApiReference.getReference(), predefinedApiReference.getApiLevel());
        });
    assert predefinedApiTypeLookup.stream()
        .allMatch(added -> added.getApiLevel().isEqualTo(lookupApiLevel(added.getReference())));
  }

  @Override
  public AndroidApiLevel getTypeApiLevel(DexType type) {
    return lookupApiLevel(type);
  }

  @Override
  public AndroidApiLevel getMethodApiLevel(DexMethod method) {
    return lookupApiLevel(method);
  }

  @Override
  public AndroidApiLevel getFieldApiLevel(DexField field) {
    return lookupApiLevel(field);
  }

  private AndroidApiLevel lookupApiLevel(DexReference reference) {
    // We use Android platform to track if an element is unknown since no occurrences of that api
    // level exists in the database.
    AndroidApiLevel result =
        lookupCache.computeIfAbsent(
            reference,
            ref -> {
              // Prefetch the data access
              if (dataAccess == null) {
                getDataAccess(options, diagnosticsHandler);
              }
              if (dataAccess.isNoBacking()) {
                return ANDROID_PLATFORM;
              }
              byte[] uniqueDescriptorForReference;
              try {
                uniqueDescriptorForReference =
                    getUniqueDescriptorForReference(
                        ref,
                        string ->
                            constantPoolCache.computeIfAbsent(
                                string, key -> dataAccess.getConstantPoolIndex(string)));
              } catch (Exception e) {
                uniqueDescriptorForReference = getNonExistingDescriptor();
              }
              if (uniqueDescriptorForReference == getNonExistingDescriptor()) {
                return ANDROID_PLATFORM;
              } else {
                byte apiLevelForReference =
                    dataAccess.getApiLevelForReference(uniqueDescriptorForReference, ref);
                return (apiLevelForReference <= 0)
                    ? ANDROID_PLATFORM
                    : AndroidApiLevel.getAndroidApiLevel(apiLevelForReference);
              }
            });
    return result == ANDROID_PLATFORM ? null : result;
  }
}
