// 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 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 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();
    return 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),
            directMethods.toArray(DexEncodedMethod.EMPTY_ARRAY),
            virtualMethods.toArray(DexEncodedMethod.EMPTY_ARRAY),
            factory.getSkipNameValidationForTesting(),
            c -> checksum,
            null);
  }
}
