// 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.graph.AppView;
import com.android.tools.r8.graph.ClassAccessFlags;
import com.android.tools.r8.graph.DexAnnotation;
import com.android.tools.r8.graph.DexAnnotationSet;
import com.android.tools.r8.graph.DexEncodedMethod;
import com.android.tools.r8.graph.DexItemFactory;
import com.android.tools.r8.graph.DexProgramClass;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.synthesis.SyntheticNaming.SyntheticKind;
import com.android.tools.r8.utils.DescriptorUtils;
import com.android.tools.r8.utils.InternalOptions;
import org.objectweb.asm.Attribute;
import org.objectweb.asm.ByteVector;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.Label;

public class SyntheticMarker {

  private static final String SYNTHETIC_MARKER_ATTRIBUTE_TYPE_NAME =
      "com.android.tools.r8.SynthesizedClass";

  public static Attribute getMarkerAttributePrototype(SyntheticNaming syntheticNaming) {
    return new MarkerAttribute(null, syntheticNaming);
  }

  public static void writeMarkerAttribute(
      ClassWriter writer, SyntheticKind kind, SyntheticItems syntheticItems) {
    writer.visitAttribute(new MarkerAttribute(kind, syntheticItems.getNaming()));
  }

  public static SyntheticMarker readMarkerAttribute(Attribute attribute) {
    if (attribute instanceof MarkerAttribute) {
      MarkerAttribute marker = (MarkerAttribute) attribute;
      return new SyntheticMarker(marker.kind, null);
    }
    return null;
  }

  private static class MarkerAttribute extends Attribute {

    private SyntheticKind kind;
    private final SyntheticNaming syntheticNaming;

    public MarkerAttribute(SyntheticKind kind, SyntheticNaming syntheticNaming) {
      super(SYNTHETIC_MARKER_ATTRIBUTE_TYPE_NAME);
      this.kind = kind;
      this.syntheticNaming = syntheticNaming;
    }

    @Override
    protected Attribute read(
        ClassReader classReader,
        int offset,
        int length,
        char[] charBuffer,
        int codeAttributeOffset,
        Label[] labels) {
      short id = classReader.readShort(offset);
      assert id >= 0;
      SyntheticKind kind = syntheticNaming.fromId(id);
      return new MarkerAttribute(kind, syntheticNaming);
    }

    @Override
    protected ByteVector write(
        ClassWriter classWriter, byte[] code, int codeLength, int maxStack, int maxLocals) {
      ByteVector byteVector = new ByteVector();
      assert 0 <= kind.getId() && kind.getId() <= Short.MAX_VALUE;
      byteVector.putShort(kind.getId());
      return byteVector;
    }
  }

  public static void addMarkerToClass(
      DexProgramClass clazz, SyntheticKind kind, InternalOptions options) {
    // TODO(b/158159959): Consider moving this to the dex writer similar to the CF case.
    assert !options.isGeneratingClassFiles();
    clazz.setAnnotations(
        clazz
            .annotations()
            .getWithAddedOrReplaced(
                DexAnnotation.createAnnotationSynthesizedClass(kind, options.itemFactory)));
  }

  public static SyntheticMarker stripMarkerFromClass(DexProgramClass clazz, AppView<?> appView) {
    if (clazz.originatesFromClassResource()) {
      SyntheticMarker marker = clazz.stripSyntheticInputMarker();
      if (marker == null) {
        return NO_MARKER;
      }
      assert marker.getContext() == null;
      DexType contextType =
          getSyntheticContextType(clazz.type, marker.kind, appView.dexItemFactory());
      SynthesizingContext context =
          SynthesizingContext.fromSyntheticInputClass(clazz, contextType, appView);
      return new SyntheticMarker(marker.kind, context);
    }
    SyntheticMarker marker = internalStripMarkerFromClass(clazz, appView);
    assert marker != NO_MARKER
        || !DexAnnotation.hasSynthesizedClassAnnotation(
            clazz.annotations(), appView.dexItemFactory(), appView.getSyntheticItems());
    return marker;
  }

  private static SyntheticMarker internalStripMarkerFromClass(
      DexProgramClass clazz, AppView<?> appView) {
    if (clazz.superType != appView.dexItemFactory().objectType) {
      return NO_MARKER;
    }
    if (isDefinitelyNotSyntheticProgramClass(clazz)) {
      return NO_MARKER;
    }
    SyntheticKind kind =
        DexAnnotation.getSynthesizedClassAnnotationInfo(
            clazz.annotations(), appView.dexItemFactory(), appView.getSyntheticItems());
    if (kind == null) {
      return NO_MARKER;
    }
    assert clazz.annotations().size() == 1;
    if (kind.isSingleSyntheticMethod()) {
      if (!clazz.interfaces.isEmpty()) {
        return NO_MARKER;
      }
      for (DexEncodedMethod method : clazz.methods()) {
        if (!SyntheticMethodBuilder.isValidSingleSyntheticMethod(method)) {
          return NO_MARKER;
        }
      }
    }
    clazz.setAnnotations(DexAnnotationSet.empty());
    DexType context = getSyntheticContextType(clazz.type, kind, appView.dexItemFactory());
    return new SyntheticMarker(
        kind, SynthesizingContext.fromSyntheticInputClass(clazz, context, appView));
  }

  // Filters out definitely not synthetic classes to avoid expensive computations on all classes.
  public static boolean isDefinitelyNotSyntheticProgramClass(DexProgramClass clazz) {
    ClassAccessFlags flags = clazz.accessFlags;
    return !flags.isSynthetic() || flags.isEnum();
  }

  private static DexType getSyntheticContextType(
      DexType type, SyntheticKind kind, DexItemFactory factory) {
    String prefix = SyntheticNaming.getPrefixForExternalSyntheticType(kind, type);
    return factory.createType(DescriptorUtils.getDescriptorFromClassBinaryName(prefix));
  }

  private static final SyntheticMarker NO_MARKER = new SyntheticMarker(null, null);

  private final SyntheticKind kind;
  private final SynthesizingContext context;

  public SyntheticMarker(SyntheticKind kind, SynthesizingContext context) {
    this.kind = kind;
    this.context = context;
  }

  public boolean isSyntheticMethods() {
    return kind != null && kind.isSingleSyntheticMethod();
  }

  public boolean isSyntheticClass() {
    return kind != null && !kind.isSingleSyntheticMethod();
  }

  public SyntheticKind getKind() {
    return kind;
  }

  public SynthesizingContext getContext() {
    return context;
  }
}
