// Copyright (c) 2018, 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.optimize.lambda.kotlin;

import com.android.tools.r8.graph.AccessFlags;
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexAnnotation;
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.DexType;
import com.android.tools.r8.graph.InnerClassAttribute;
import com.android.tools.r8.ir.optimize.lambda.CaptureSignature;
import com.android.tools.r8.ir.optimize.lambda.LambdaGroup.LambdaStructureError;
import com.android.tools.r8.ir.optimize.lambda.LambdaGroupId;
import com.android.tools.r8.kotlin.Kotlin;
import com.android.tools.r8.shaking.AppInfoWithLiveness;
import java.util.List;

public abstract class KotlinLambdaGroupIdFactory implements KotlinLambdaConstants {
  KotlinLambdaGroupIdFactory() {
  }

  // Creates a lambda group id for kotlin style lambda. Should never return null, if the lambda
  // does not pass pre-requirements (mostly by not meeting high-level structure expectations)
  // should throw LambdaStructureError leaving the caller to decide if/how it needs to be reported.
  //
  // At this point we only perform high-level checks before qualifying the lambda as a candidate
  // for merging and assigning lambda group id. We can NOT perform checks on method bodies since
  // they may not be converted yet, we'll do that in KStyleLambdaClassValidator.
  public static LambdaGroupId create(
      AppView<AppInfoWithLiveness> appView, Kotlin kotlin, DexClass lambda)
      throws LambdaStructureError {

    assert lambda.getKotlinInfo().isSyntheticClass();
    if (lambda.getKotlinInfo().asSyntheticClass().isKotlinStyleLambda()) {
      return KStyleLambdaGroupIdFactory.INSTANCE.validateAndCreate(appView, kotlin, lambda);
    }

    assert lambda.getKotlinInfo().asSyntheticClass().isJavaStyleLambda();
    return JStyleLambdaGroupIdFactory.INSTANCE.validateAndCreate(appView, kotlin, lambda);
  }

  abstract LambdaGroupId validateAndCreate(
      AppView<AppInfoWithLiveness> appView, Kotlin kotlin, DexClass lambda)
      throws LambdaStructureError;

  abstract void validateSuperclass(Kotlin kotlin, DexClass lambda) throws LambdaStructureError;

  abstract DexType validateInterfaces(Kotlin kotlin, DexClass lambda) throws LambdaStructureError;

  DexEncodedMethod validateVirtualMethods(DexClass lambda) throws LambdaStructureError {
    DexEncodedMethod mainMethod = null;

    for (DexEncodedMethod method : lambda.virtualMethods()) {
      if (method.accessFlags.materialize() == MAIN_METHOD_FLAGS.materialize()) {
        if (mainMethod != null) {
          throw new LambdaStructureError("more than one main method found");
        }
        mainMethod = method;
      } else {
        checkAccessFlags("unexpected virtual method access flags",
            method.accessFlags, BRIDGE_METHOD_FLAGS, BRIDGE_METHOD_FLAGS_FIXED);
        checkDirectMethodAnnotations(method);
      }
    }

    if (mainMethod == null) {
      // Missing main method may be a result of tree shaking.
      throw new LambdaStructureError("no main method found", false);
    }
    return mainMethod;
  }

  InnerClassAttribute validateInnerClasses(DexClass lambda) throws LambdaStructureError {
    List<InnerClassAttribute> innerClasses = lambda.getInnerClasses();
    if (innerClasses != null) {
      for (InnerClassAttribute inner : innerClasses) {
        if (inner.getInner() == lambda.type) {
          if (!inner.isAnonymous()) {
            throw new LambdaStructureError("is not anonymous");
          }
          return inner;
        }
      }
    }
    return null;
  }

  public static boolean hasValidAnnotations(Kotlin kotlin, DexClass lambda) {
    for (DexAnnotation annotation : lambda.annotations().annotations) {
      if (annotation.annotation.type == kotlin.factory.kotlinMetadataType) {
        continue;
      }
      return false;
    }
    return true;
  }

  String validateAnnotations(AppView<AppInfoWithLiveness> appView, Kotlin kotlin, DexClass lambda)
      throws LambdaStructureError {
    for (DexAnnotation annotation : lambda.liveAnnotations(appView).annotations) {
      if (annotation.annotation.type == appView.dexItemFactory().kotlinMetadataType) {
        // Ignore kotlin metadata on lambda classes. Metadata on synthetic
        // classes exists but is not used in the current Kotlin version (1.2.21)
        // and newly generated lambda _group_ class is not exactly a kotlin class.
        continue;
      }

      assert !hasValidAnnotations(kotlin, lambda);
      throw new LambdaStructureError(
          "unexpected annotation: " + annotation.annotation.type.toSourceString());
    }
    assert hasValidAnnotations(kotlin, lambda);
    return lambda.getClassSignature().toString();
  }

  void validateStaticFields(Kotlin kotlin, DexClass lambda) throws LambdaStructureError {
    List<DexEncodedField> staticFields = lambda.staticFields();
    if (staticFields.size() == 1) {
      DexEncodedField field = staticFields.get(0);
      if (field.field.name != kotlin.functional.kotlinStyleLambdaInstanceName ||
          field.field.type != lambda.type || !field.accessFlags.isPublic() ||
          !field.accessFlags.isFinal() || !field.accessFlags.isStatic()) {
        throw new LambdaStructureError("unexpected static field " + field.toSourceString());
      }
      // No state if the lambda is a singleton.
      if (lambda.instanceFields().size() > 0) {
        throw new LambdaStructureError("has instance fields along with INSTANCE");
      }
      checkAccessFlags("static field access flags", field.accessFlags, SINGLETON_FIELD_FLAGS);
      checkFieldAnnotations(field);

    } else if (staticFields.size() > 1) {
      throw new LambdaStructureError(
          "only one static field max expected, found " + staticFields.size());
    }
  }

  String validateInstanceFields(DexClass lambda, boolean accessRelaxed)
      throws LambdaStructureError {
    List<DexEncodedField> instanceFields = lambda.instanceFields();
    for (DexEncodedField field : instanceFields) {
      checkAccessFlags("capture field access flags", field.accessFlags,
          accessRelaxed ? CAPTURE_FIELD_FLAGS_RELAXED : CAPTURE_FIELD_FLAGS);
      checkFieldAnnotations(field);
    }
    return CaptureSignature.getCaptureSignature(instanceFields);
  }

  void validateDirectMethods(DexClass lambda) throws LambdaStructureError {
    for (DexEncodedMethod method : lambda.directMethods()) {
      if (method.isClassInitializer()) {
        // We expect to see class initializer only if there is a singleton field.
        if (lambda.staticFields().size() != 1) {
          throw new LambdaStructureError("has static initializer, but no singleton field");
        }
        checkAccessFlags(
            "unexpected static initializer access flags",
            method.accessFlags.getOriginalAccessFlags(),
            CLASS_INITIALIZER_FLAGS);
        checkDirectMethodAnnotations(method);
      } else if (method.isStatic()) {
        throw new LambdaStructureError(
            "unexpected static method: " + method.method.toSourceString());
      } else if (method.isInstanceInitializer()) {
        // Lambda class is expected to have one constructor
        // with parameters matching capture signature.
        DexType[] parameters = method.method.proto.parameters.values;
        List<DexEncodedField> instanceFields = lambda.instanceFields();
        if (parameters.length != instanceFields.size()) {
          throw new LambdaStructureError("constructor parameters don't match captured values.");
        }
        for (int i = 0; i < parameters.length; i++) {
          // Kotlin compiler sometimes reshuffles the parameters so that their order
          // in the constructor don't match order of capture fields. We could add
          // support for it, but it happens quite rarely so don't bother for now.
          if (parameters[i] != instanceFields.get(i).field.type) {
            throw new LambdaStructureError(
                "constructor parameters don't match captured values.", false);
          }
        }
        checkAccessFlags("unexpected constructor access flags",
            method.accessFlags, CONSTRUCTOR_FLAGS, CONSTRUCTOR_FLAGS_RELAXED);
        checkDirectMethodAnnotations(method);

      } else if (method.isPrivateMethod()) {
        // TODO(b/135975229)
        throw new LambdaStructureError("private method: " + method.method.toSourceString());
      } else {
        assert false;
        throw new LambdaStructureError(
            "unexpected method encountered: " + method.method.toSourceString());
      }
    }
  }

  private static void checkDirectMethodAnnotations(DexEncodedMethod method)
      throws LambdaStructureError {
    if (!method.annotations().isEmpty()) {
      throw new LambdaStructureError(
          "unexpected method annotations ["
              + method.annotations().toSmaliString()
              + "] on "
              + method.method.toSourceString());
    }
    if (!method.parameterAnnotationsList.isEmpty()) {
      throw new LambdaStructureError(
          "unexpected method parameters annotations ["
              + method.parameterAnnotationsList.toSmaliString()
              + "] on "
              + method.method.toSourceString());
    }
  }

  private static void checkFieldAnnotations(DexEncodedField field) throws LambdaStructureError {
    if (field.hasAnnotation()) {
      throw new LambdaStructureError(
          "unexpected field annotations ["
              + field.annotations().toSmaliString()
              + "] on "
              + field.field.toSourceString());
    }
  }

  @SafeVarargs
  static <T extends AccessFlags> void checkAccessFlags(
      String message, T actual, T... expected) throws LambdaStructureError {
    checkAccessFlags(message, actual.materialize(), expected);
  }

  @SafeVarargs
  private static <T extends AccessFlags> void checkAccessFlags(
      String message, int actual, T... expected) throws LambdaStructureError {
    for (T flag : expected) {
      if (actual == flag.materialize()) {
        return;
      }
    }
    throw new LambdaStructureError(message);
  }
}
