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

import com.android.tools.r8.dex.IndexedItemCollection;
import com.android.tools.r8.naming.NamingLens;
import com.android.tools.r8.shaking.AppInfoWithLiveness;
import com.android.tools.r8.utils.InternalOptions;
import java.util.Collections;
import java.util.List;
import java.util.function.Consumer;
import org.objectweb.asm.ClassWriter;

/** Representation of an entry in the Java InnerClasses attribute table. */
public class InnerClassAttribute {

  // Access flags to the inner class as declared in the program source.
  private final int access;

  // Type of the inner class.
  private final DexType inner;

  // Type of the enclosing class, null if the inner class is top-level, local or anonymous.
  private final DexType outer;

  // Short name of the inner class, null if the inner class is anonymous.
  private final DexString innerName;

  // Create a named inner-class attribute, but with some arbitrary/unknown name.
  // This is needed to partially map back to the Java attribute structures when reading DEX inputs.
  public static InnerClassAttribute createUnknownNamedInnerClass(DexType inner, DexType outer) {
    return new InnerClassAttribute(0, inner, outer, DexItemFactory.unknownTypeName);
  }

  public InnerClassAttribute(int access, DexType inner, DexType outer, DexString innerName) {
    assert inner != null;
    this.access = access;
    this.inner = inner;
    this.outer = outer;
    this.innerName = innerName;
  }

  public static List<InnerClassAttribute> emptyList() {
    return Collections.emptyList();
  }

  public void forEachType(Consumer<DexType> consumer) {
    if (inner != null) {
      consumer.accept(inner);
    }
    if (outer != null) {
      consumer.accept(outer);
    }
  }

  public boolean isNamed() {
    return innerName != null;
  }

  public boolean isAnonymous() {
    return innerName == null;
  }

  public int getAccess() {
    return access;
  }

  public DexType getInner() {
    return inner;
  }

  public DexType getOuter() {
    return outer;
  }

  public DexString getInnerName() {
    return innerName;
  }

  public void write(ClassWriter writer, NamingLens lens, InternalOptions options) {
    String internalName = lens.lookupInternalName(inner);
    writer.visitInnerClass(
        internalName,
        outer == null ? null : lens.lookupInternalName(outer),
        innerName == null ? null : lens.lookupInnerName(this, options).toString(),
        access);
  }

  public void collectIndexedItems(AppView<?> appView, IndexedItemCollection indexedItems) {
    inner.collectIndexedItems(appView, indexedItems);
    if (outer != null) {
      outer.collectIndexedItems(appView, indexedItems);
    }
    if (innerName != null) {
      innerName.collectIndexedItems(indexedItems);
    }
  }

  public DexType getLiveContext(AppView<? extends AppInfoWithLiveness> appView) {
    DexType context = getOuter();
    if (context == null) {
      DexClass inner = appView.definitionFor(getInner());
      if (inner != null && inner.getEnclosingMethodAttribute() != null) {
        EnclosingMethodAttribute enclosingMethodAttribute = inner.getEnclosingMethodAttribute();
        if (enclosingMethodAttribute.getEnclosingClass() != null) {
          context = enclosingMethodAttribute.getEnclosingClass();
        } else {
          DexMethod enclosingMethod = enclosingMethodAttribute.getEnclosingMethod();
          if (!appView.appInfo().isLiveMethod(enclosingMethod)) {
            // EnclosingMethodAttribute will be pruned as it references the pruned method.
            // Hence, the current InnerClassAttribute will be removed too. No live context.
            return null;
          }
          context = enclosingMethod.holder;
        }
      }
    }
    return context;
  }

  @Override
  public String toString() {
    return "[access : " + Integer.toHexString(access)
        + ", inner: " + inner.toDescriptorString()
        + ", outer: " + (outer == null ? "null" : outer.toDescriptorString())
        + ", innerName: " + (innerName == null ? "(anonymous)" : innerName.toString())
        + "]";
  }
}
