// 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 java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.function.Consumer;

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

  private final DexItemFactory factory;

  private final DexType type;
  private final Origin origin;

  private boolean isAbstract = false;
  private Kind originKind;
  private DexType superType;
  private DexTypeList interfaces = DexTypeList.empty();
  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<>();

  SyntheticClassBuilder(DexType type, SynthesizingContext context, DexItemFactory factory) {
    this.factory = factory;
    this.type = type;
    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 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 setOriginKind(Kind originKind) {
    this.originKind = originKind;
    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;
    ClassAccessFlags accessFlags =
        ClassAccessFlags.fromSharedAccessFlags(
            flag | Constants.ACC_PUBLIC | Constants.ACC_SYNTHETIC);
    DexString sourceFile = null;
    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,
            ClassSignature.noSignature(),
            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);
  }
}
