// 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 com.android.tools.r8.kotlin.KotlinMetadataSynthesizer.toRenamedClassifier;
import static com.android.tools.r8.kotlin.KotlinMetadataSynthesizer.toRenamedKmConstructor;
import static com.android.tools.r8.kotlin.KotlinMetadataSynthesizer.toRenamedKmType;
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.naming.NamingLens;
import com.android.tools.r8.shaking.AppInfoWithLiveness;
import com.android.tools.r8.utils.StringUtils;
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, NamingLens lens) {
    if (appView.options().enableKotlinMetadataRewritingForRenamedClasses
        && lens.lookupType(clazz.type, appView.dexItemFactory()) != clazz.type) {
      String renamedClassifier = toRenamedClassifier(clazz.type, appView, lens);
      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 = toRenamedKmType(itfType, null, appView, lens);
      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 = toRenamedKmType(clazz.superType, null, appView, lens);
      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 : appView.appInfo().allImmediateSubtypes(clazz.type)) {
        String classifier = toRenamedClassifier(subtype, appView, lens);
        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 = toRenamedKmConstructor(method, appView, lens);
      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(appView, lens);
  }

  @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);
    sb.append("Metadata.Class {");
    sb.append(StringUtils.LINE_SEPARATOR);
    sb.append(kmDeclarationContainerToString(indent + INDENT));
    sb.append(indent);
    sb.append("}");
    return sb.toString();
  }
}
