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

import com.android.tools.r8.ProgramResource.Kind;
import com.android.tools.r8.dex.Constants;
import com.android.tools.r8.graph.ClassAccessFlags;
import com.android.tools.r8.graph.ClassKind;
import com.android.tools.r8.graph.DexAnnotationSet;
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.DexItemFactory;
import com.android.tools.r8.graph.DexString;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.graph.DexTypeList;
import com.android.tools.r8.graph.EnclosingMethodAttribute;
import com.android.tools.r8.graph.GenericSignature.ClassSignature;
import com.android.tools.r8.graph.InnerClassAttribute;
import com.android.tools.r8.graph.NestHostClassAttribute;
import com.android.tools.r8.graph.NestMemberClassAttribute;
import com.android.tools.r8.origin.Origin;
import com.android.tools.r8.synthesis.SyntheticNaming.SyntheticKind;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.function.Consumer;

public abstract class SyntheticClassBuilder<
    B extends SyntheticClassBuilder<B, C>, C extends DexClass> {

  private final DexItemFactory factory;

  private final DexType type;
  private final SyntheticKind syntheticKind;
  private final Origin origin;

  private boolean isAbstract = false;
  private boolean isInterface = false;
  private Kind originKind;
  private DexType superType;
  private DexTypeList interfaces = DexTypeList.empty();
  private DexString sourceFile = null;
  private boolean useSortedMethodBacking = false;
  private List<DexEncodedField> staticFields = new ArrayList<>();
  private List<DexEncodedField> instanceFields = new ArrayList<>();
  private List<DexEncodedMethod> directMethods = new ArrayList<>();
  private List<DexEncodedMethod> virtualMethods = new ArrayList<>();
  private List<SyntheticMethodBuilder> methods = new ArrayList<>();
  private ClassSignature signature = ClassSignature.noSignature();

  SyntheticClassBuilder(
      DexType type,
      SyntheticKind syntheticKind,
      SynthesizingContext context,
      DexItemFactory factory) {
    this.factory = factory;
    this.type = type;
    this.syntheticKind = syntheticKind;
    this.origin = context.getInputContextOrigin();
    this.superType = factory.objectType;
  }

  public abstract B self();

  public abstract ClassKind<C> getClassKind();

  public DexItemFactory getFactory() {
    return factory;
  }

  public DexType getType() {
    return type;
  }

  public SyntheticKind getSyntheticKind() {
    return syntheticKind;
  }

  public B setInterfaces(List<DexType> interfaces) {
    this.interfaces =
        interfaces.isEmpty()
            ? DexTypeList.empty()
            : new DexTypeList(interfaces.toArray(DexType.EMPTY_ARRAY));
    return self();
  }

  public B setAbstract() {
    isAbstract = true;
    return self();
  }

  public B setInterface() {
    setAbstract();
    isInterface = true;
    return self();
  }

  public B setOriginKind(Kind originKind) {
    this.originKind = originKind;
    return self();
  }

  public B setSourceFile(DexString sourceFile) {
    this.sourceFile = sourceFile;
    return self();
  }

  public B setGenericSignature(ClassSignature signature) {
    this.signature = signature;
    return self();
  }

  public B setStaticFields(List<DexEncodedField> fields) {
    staticFields.clear();
    staticFields.addAll(fields);
    return self();
  }

  public B setInstanceFields(List<DexEncodedField> fields) {
    instanceFields.clear();
    instanceFields.addAll(fields);
    return self();
  }

  public B setDirectMethods(Iterable<DexEncodedMethod> methods) {
    directMethods.clear();
    methods.forEach(directMethods::add);
    return self();
  }

  public B setVirtualMethods(Iterable<DexEncodedMethod> methods) {
    virtualMethods.clear();
    methods.forEach(virtualMethods::add);
    return self();
  }

  public B addMethod(Consumer<SyntheticMethodBuilder> fn) {
    SyntheticMethodBuilder method = new SyntheticMethodBuilder(this);
    fn.accept(method);
    methods.add(method);
    return self();
  }

  public B setUseSortedMethodBacking(boolean useSortedMethodBacking) {
    this.useSortedMethodBacking = useSortedMethodBacking;
    return self();
  }

  public C build() {
    int flag = isAbstract ? Constants.ACC_ABSTRACT : Constants.ACC_FINAL;
    int itfFlag = isInterface ? Constants.ACC_INTERFACE : 0;
    assert !isInterface || isAbstract;
    ClassAccessFlags accessFlags =
        ClassAccessFlags.fromSharedAccessFlags(
            flag | itfFlag | Constants.ACC_PUBLIC | Constants.ACC_SYNTHETIC);
    NestHostClassAttribute nestHost = null;
    List<NestMemberClassAttribute> nestMembers = Collections.emptyList();
    EnclosingMethodAttribute enclosingMembers = null;
    List<InnerClassAttribute> innerClasses = Collections.emptyList();
    for (SyntheticMethodBuilder builder : methods) {
      DexEncodedMethod method = builder.build();
      if (method.isNonPrivateVirtualMethod()) {
        virtualMethods.add(method);
      } else {
        directMethods.add(method);
      }
    }
    long checksum =
        7 * (long) directMethods.hashCode()
            + 11 * (long) virtualMethods.hashCode()
            + 13 * (long) staticFields.hashCode()
            + 17 * (long) instanceFields.hashCode();
    C clazz =
        getClassKind()
            .create(
                type,
                originKind,
                origin,
                accessFlags,
                superType,
                interfaces,
                sourceFile,
                nestHost,
                nestMembers,
                enclosingMembers,
                innerClasses,
                signature,
                DexAnnotationSet.empty(),
                staticFields.toArray(DexEncodedField.EMPTY_ARRAY),
                instanceFields.toArray(DexEncodedField.EMPTY_ARRAY),
                DexEncodedMethod.EMPTY_ARRAY,
                DexEncodedMethod.EMPTY_ARRAY,
                factory.getSkipNameValidationForTesting(),
                c -> checksum,
                null);
    if (useSortedMethodBacking) {
      clazz.getMethodCollection().useSortedBacking();
    }
    clazz.setDirectMethods(directMethods.toArray(DexEncodedMethod.EMPTY_ARRAY));
    clazz.setVirtualMethods(virtualMethods.toArray(DexEncodedMethod.EMPTY_ARRAY));
    return clazz;
  }
}
