// 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.utils.codeinspector;

import static com.android.tools.r8.ir.desugar.InterfaceMethodRewriter.COMPANION_CLASS_NAME_SUFFIX;

import com.android.tools.r8.graph.DexMethod;
import com.android.tools.r8.graph.DexProgramClass;
import com.android.tools.r8.naming.ClassNamingForNameMapper;
import com.android.tools.r8.naming.MemberNaming.MethodSignature;
import com.android.tools.r8.references.ClassReference;
import com.android.tools.r8.references.MethodReference;
import com.android.tools.r8.references.Reference;
import com.android.tools.r8.references.TypeReference;
import com.android.tools.r8.smali.SmaliBuilder;
import com.android.tools.r8.utils.ListUtils;
import com.google.common.base.Predicates;
import com.google.common.collect.ImmutableList;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.function.Consumer;
import java.util.function.Predicate;
import kotlinx.metadata.jvm.KotlinClassMetadata;
import org.junit.rules.TemporaryFolder;

public abstract class ClassSubject extends Subject {

  protected final ClassReference reference;
  protected final CodeInspector codeInspector;

  public ClassSubject(CodeInspector codeInspector, ClassReference reference) {
    this.codeInspector = codeInspector;
    this.reference = reference;
  }

  public abstract void forAllMethods(Consumer<FoundMethodSubject> inspection);

  public final List<FoundMethodSubject> allMethods() {
    return allMethods(Predicates.alwaysTrue());
  }

  public final List<FoundMethodSubject> allMethods(Predicate<FoundMethodSubject> predicate) {
    ImmutableList.Builder<FoundMethodSubject> builder = ImmutableList.builder();
    forAllMethods(
        methodSubject -> {
          if (predicate.test(methodSubject)) {
            builder.add(methodSubject);
          }
        });
    return builder.build();
  }

  public abstract void forAllVirtualMethods(Consumer<FoundMethodSubject> inspection);

  public final List<FoundMethodSubject> virtualMethods() {
    return virtualMethods(Predicates.alwaysTrue());
  }

  public final List<FoundMethodSubject> virtualMethods(Predicate<FoundMethodSubject> predicate) {
    ImmutableList.Builder<FoundMethodSubject> builder = ImmutableList.builder();
    forAllVirtualMethods(
        methodSubject -> {
          if (predicate.test(methodSubject)) {
            builder.add(methodSubject);
          }
        });
    return builder.build();
  }

  public MethodSubject method(MethodReference method) {
    return method(
        (method.getReturnType() == null ? "void" : method.getReturnType().getTypeName()),
        method.getMethodName(),
        ListUtils.map(method.getFormalTypes(), TypeReference::getTypeName));
  }

  public MethodSubject method(Method method) {
    List<String> parameters = new ArrayList<>();
    for (Class<?> parameterType : method.getParameterTypes()) {
      parameters.add(parameterType.getTypeName());
    }
    return method(method.getReturnType().getTypeName(), method.getName(), parameters);
  }

  public final MethodSubject method(String returnType, String name) {
    return method(returnType, name, ImmutableList.of());
  }

  public MethodSubject method(String returnType, String name, String... parameters) {
    return method(returnType, name, Arrays.asList(parameters));
  }

  public abstract MethodSubject method(String returnType, String name, List<String> parameters);

  public abstract MethodSubject uniqueInstanceInitializer();

  public abstract MethodSubject uniqueMethodWithName(String name);

  public MethodSubject mainMethod() {
    return method("void", "main", ImmutableList.of("java.lang.String[]"));
  }

  public MethodSubject clinit() {
    return method("void", "<clinit>", ImmutableList.of());
  }

  public MethodSubject init(List<String> parameters) {
    return method("void", "<init>", parameters);
  }

  public MethodSubject init(String... parameters) {
    return init(Arrays.asList(parameters));
  }

  public MethodSubject method(MethodSignature signature) {
    return method(signature.type, signature.name, ImmutableList.copyOf(signature.parameters));
  }

  public MethodSubject method(SmaliBuilder.MethodSignature signature) {
    return method(
        signature.returnType, signature.name, ImmutableList.copyOf(signature.parameterTypes));
  }

  public abstract void forAllFields(Consumer<FoundFieldSubject> inspection);

  public final List<FoundFieldSubject> allFields() {
    ImmutableList.Builder<FoundFieldSubject> builder = ImmutableList.builder();
    forAllFields(builder::add);
    return builder.build();
  }

  public abstract void forAllInstanceFields(Consumer<FoundFieldSubject> inspection);

  public abstract void forAllStaticFields(Consumer<FoundFieldSubject> inspection);

  public final List<FoundFieldSubject> allInstanceFields() {
    ImmutableList.Builder<FoundFieldSubject> builder = ImmutableList.builder();
    forAllInstanceFields(builder::add);
    return builder.build();
  }

  public final List<FoundFieldSubject> allStaticFields() {
    ImmutableList.Builder<FoundFieldSubject> builder = ImmutableList.builder();
    forAllStaticFields(builder::add);
    return builder.build();
  }

  public abstract FieldSubject field(String type, String name);

  public abstract FieldSubject uniqueFieldWithName(String name);

  public abstract FieldSubject uniqueFieldWithFinalName(String name);

  public FoundClassSubject asFoundClassSubject() {
    return null;
  }

  public abstract boolean isAbstract();

  public abstract boolean isAnnotation();

  public abstract boolean isPublic();

  public String dumpMethods() {
    StringBuilder dump = new StringBuilder();
    forAllMethods(
        (FoundMethodSubject method) ->
            dump.append(method.getMethod().toString()).append(method.getMethod().codeToString()));
    return dump.toString();
  }

  public abstract DexProgramClass getDexProgramClass();

  public abstract AnnotationSubject annotation(String name);

  public abstract String getOriginalName();

  public abstract String getOriginalDescriptor();

  public abstract String getOriginalBinaryName();

  public abstract ClassReference getFinalReference();

  public abstract String getFinalName();

  public abstract String getFinalDescriptor();

  public abstract String getFinalBinaryName();

  public abstract boolean isMemberClass();

  public abstract boolean isLocalClass();

  public abstract boolean isAnonymousClass();

  public abstract boolean isSynthesizedJavaLambdaClass();

  public abstract DexMethod getFinalEnclosingMethod();

  public abstract String getOriginalSignatureAttribute();

  public abstract String getFinalSignatureAttribute();

  public abstract KmClassSubject getKmClass();

  public abstract KmPackageSubject getKmPackage();

  public abstract KotlinClassMetadata getKotlinClassMetadata();

  public ClassSubject toCompanionClass() {
    String descriptor = reference.getDescriptor();
    return codeInspector.clazz(
        Reference.classFromDescriptor(
            descriptor.substring(0, descriptor.length() - 1) + COMPANION_CLASS_NAME_SUFFIX + ";"));
  }

  public abstract ClassNamingForNameMapper getNaming();

  public abstract String disassembleUsingJavap(boolean verbose) throws Exception;

  public abstract String asmify(TemporaryFolder tempFolder, boolean debug) throws Exception;
}
