// 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.kotlin;

import static com.android.tools.r8.kotlin.Kotlin.addKotlinPrefix;
import static com.android.tools.r8.kotlin.KotlinMetadataSynthesizer.toKmType;
import static kotlinx.metadata.Flag.IS_SEALED;

import com.android.tools.r8.graph.AppView;
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.DexField;
import com.android.tools.r8.graph.DexProgramClass;
import com.android.tools.r8.graph.DexString;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.graph.InnerClassAttribute;
import com.android.tools.r8.graph.SubtypingInfo;
import com.android.tools.r8.naming.NamingLens;
import com.android.tools.r8.shaking.AppInfoWithLiveness;
import java.util.List;
import kotlinx.metadata.KmClass;
import kotlinx.metadata.KmConstructor;
import kotlinx.metadata.KmType;
import kotlinx.metadata.jvm.KotlinClassHeader;
import kotlinx.metadata.jvm.KotlinClassMetadata;

public class KotlinClass extends KotlinInfo<KotlinClassMetadata.Class> {

  KmClass kmClass;

  DexField companionObject = null;
  DexProgramClass hostClass = null;

  static KotlinClass fromKotlinClassMetadata(
      KotlinClassMetadata kotlinClassMetadata, DexClass clazz) {
    assert kotlinClassMetadata instanceof KotlinClassMetadata.Class;
    KotlinClassMetadata.Class kClass = (KotlinClassMetadata.Class) kotlinClassMetadata;
    return new KotlinClass(kClass, clazz);
  }

  private KotlinClass(KotlinClassMetadata.Class metadata, DexClass clazz) {
    super(metadata, clazz);
  }

  void foundCompanionObject(DexEncodedField companionObject) {
    // Companion cannot be nested. If this class is a host (and about to store a field that holds
    // a companion object), it should not have a host class.
    assert hostClass == null;
    this.companionObject = companionObject.field;
  }

  boolean hasCompanionObject() {
    return companionObject != null;
  }

  DexType getCompanionObjectType() {
    return hasCompanionObject() ? companionObject.type : null;
  }

  void linkHostClass(DexProgramClass hostClass) {
    // Companion cannot be nested. If this class is a companion object (and about to link to its
    // host class), it should not have a companion object.
    assert companionObject == null;
    this.hostClass = hostClass;
  }

  @Override
  void processMetadata(KotlinClassMetadata.Class metadata) {
    kmClass = metadata.toKmClass();
  }

  @Override
  void rewrite(AppView<AppInfoWithLiveness> appView, SubtypingInfo subtypingInfo, NamingLens lens) {
    KotlinMetadataSynthesizer synthesizer = new KotlinMetadataSynthesizer(appView, lens, this);
    if (appView.options().enableKotlinMetadataRewritingForRenamedClasses
        && lens.lookupType(clazz.type, appView.dexItemFactory()) != clazz.type) {
      String renamedClassifier = synthesizer.toRenamedClassifier(clazz.type);
      if (renamedClassifier != null) {
        assert !kmClass.getName().equals(renamedClassifier);
        kmClass.setName(renamedClassifier);
      }
    }

    // Rewriting upward hierarchy.
    List<KmType> superTypes = kmClass.getSupertypes();
    superTypes.clear();
    for (DexType itfType : clazz.interfaces.values) {
      // TODO(b/129925954): Use GenericSignature.ClassSignature#superInterfaceSignatures
      KmType kmType = synthesizer.toRenamedKmType(itfType, null, null, getTypeParameters());
      if (kmType != null) {
        superTypes.add(kmType);
      }
    }
    assert clazz.superType != null;
    if (clazz.superType != appView.dexItemFactory().objectType) {
      // TODO(b/129925954): Use GenericSignature.ClassSignature#superClassSignature
      KmType kmTypeForSupertype =
          synthesizer.toRenamedKmType(clazz.superType, null, null, getTypeParameters());
      if (kmTypeForSupertype != null) {
        superTypes.add(kmTypeForSupertype);
      }
    } else if (clazz.isInterface()) {
      superTypes.add(toKmType(addKotlinPrefix("Any;")));
    }

    // Rewriting downward hierarchies: nested, including companion class.
    // Note that `kotlinc` uses these nested classes to determine which classes to look up when
    // resolving declarations in the companion object, e.g., Host.Companion.prop and Host.prop.
    // Thus, users (in particular, library developers) should keep InnerClasses and EnclosingMethod
    // attributes if declarations in the companion need to be exposed.
    List<String> nestedClasses = kmClass.getNestedClasses();
    nestedClasses.clear();
    for (InnerClassAttribute innerClassAttribute : clazz.getInnerClasses()) {
      // Skip InnerClass attribute for itself.
      // Otherwise, an inner class would have itself as a nested class.
      if (clazz.getInnerClassAttributeForThisClass() == innerClassAttribute) {
        continue;
      }
      DexString renamedInnerName = lens.lookupInnerName(innerClassAttribute, appView.options());
      if (renamedInnerName != null) {
        nestedClasses.add(renamedInnerName.toString());
      }
    }

    // Rewriting downward hierarchies: sealed.
    List<String> sealedSubclasses = kmClass.getSealedSubclasses();
    sealedSubclasses.clear();
    if (IS_SEALED.invoke(kmClass.getFlags())) {
      for (DexType subtype : subtypingInfo.allImmediateSubtypes(clazz.type)) {
        String classifier = synthesizer.toRenamedClassifier(subtype);
        if (classifier != null) {
          sealedSubclasses.add(classifier);
        }
      }
    }

    if (!appView.options().enableKotlinMetadataRewritingForMembers) {
      return;
    }

    // Rewriting constructors.
    List<KmConstructor> constructors = kmClass.getConstructors();
    constructors.clear();
    for (DexEncodedMethod method : clazz.directMethods()) {
      if (!method.isInstanceInitializer()) {
        continue;
      }
      KmConstructor constructor = synthesizer.toRenamedKmConstructor(clazz, method);
      if (constructor != null) {
        constructors.add(constructor);
      }
    }

    // Rewriting companion object if any.
    if (kmClass.getCompanionObject() != null && hasCompanionObject()) {
      kmClass.setCompanionObject(lens.lookupName(companionObject).toString());
    }

    // TODO(b/151193864): enum entries

    rewriteDeclarationContainer(synthesizer);
  }

  @Override
  KotlinClassHeader createHeader() {
    KotlinClassMetadata.Class.Writer writer = new KotlinClassMetadata.Class.Writer();
    kmClass.accept(writer);
    return writer.write().getHeader();
  }

  @Override
  public Kind getKind() {
    return Kind.Class;
  }

  @Override
  public boolean isClass() {
    return true;
  }

  @Override
  public KotlinClass asClass() {
    return this;
  }

  @Override
  public String toString(String indent) {
    StringBuilder sb = new StringBuilder(indent);
    appendKmSection(
        indent,
        "Metadata.Class",
        sb,
        newIndent -> {
          appendKmClass(newIndent, sb, kmClass);
        });
    return sb.toString();
  }
}
