// Copyright 2019 The Bazel Authors. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package com.google.devtools.build.android.desugar.nest;

import com.google.devtools.build.android.desugar.langmodel.ClassAttributeRecord;
import com.google.devtools.build.android.desugar.langmodel.ClassAttributes;
import com.google.devtools.build.android.desugar.langmodel.ClassAttributes.ClassAttributesBuilder;
import com.google.devtools.build.android.desugar.langmodel.ClassMemberRecord;
import com.google.devtools.build.android.desugar.langmodel.ClassName;
import com.google.devtools.build.android.desugar.langmodel.FieldKey;
import com.google.devtools.build.android.desugar.langmodel.LangModelHelper;
import com.google.devtools.build.android.desugar.langmodel.MethodKey;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.FieldVisitor;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;

/**
 * A visitor that collects declared private members (fields, constructors and methods), and
 * delegates to a method visitor to track the references to these members.
 */
final class CrossMateMainCollector extends ClassVisitor {

  /** The project-wise class member records. */
  private final ClassMemberRecord memberRecord;

  private final ClassAttributeRecord classAttributeRecord;

  /**
   * An class member record to stage member record candidates, merging into the project-wise member
   * record during the {@link #visitEnd()} where eligible conditions are specified.
   */
  private final ClassMemberRecord stagingMemberRecord = ClassMemberRecord.create();

  private final ClassAttributesBuilder classAttributesBuilder = ClassAttributes.builder();

  private ClassName className;
  private int classAccessCode;
  private boolean isInNest;

  public CrossMateMainCollector(
      ClassMemberRecord memberRecord, ClassAttributeRecord classAttributeRecord) {
    super(Opcodes.ASM7);
    this.memberRecord = memberRecord;
    this.classAttributeRecord = classAttributeRecord;
  }

  @Override
  public void visit(
      int version,
      int access,
      String name,
      String signature,
      String superName,
      String[] interfaces) {
    className = ClassName.create(name);
    classAccessCode = access;
    classAttributesBuilder.setClassBinaryName(className);
    super.visit(
        Math.min(version, NestDesugarConstants.MIN_VERSION),
        access,
        name,
        signature,
        superName,
        interfaces);
  }

  @Override
  public FieldVisitor visitField(
      int access, String name, String descriptor, String signature, Object value) {
    if ((access & Opcodes.ACC_PRIVATE) != 0) {
      stagingMemberRecord.logMemberDecl(
          FieldKey.create(className, name, descriptor), classAccessCode, access);
    }
    return super.visitField(access, name, descriptor, signature, value);
  }

  @Override
  public MethodVisitor visitMethod(
      int access, String name, String descriptor, String signature, String[] exceptions) {
    MethodKey methodKey = MethodKey.create(className, name, descriptor);
    if ((access & Opcodes.ACC_PRIVATE) != 0 && !isInDeclOmissionList(methodKey)) {
      stagingMemberRecord.logMemberDecl(methodKey, classAccessCode, access);
    }
    return new CrossMateRefCollector(
        super.visitMethod(access, name, descriptor, signature, exceptions),
        methodKey,
        stagingMemberRecord);
  }

  /**
   * The method declaration will be explicitly omitted.
   *
   * <p>TODO(deltazulu): Refine this list and condition check. e.g. check ACC_SYNTHETIC flag.
   */
  private static boolean isInDeclOmissionList(MethodKey methodKey) {
    return methodKey.name().startsWith("lambda$") // handled by LambdaDesugaring.
        || methodKey.name().equals("$deserializeLambda$") // handled by LambdaDesugaring.
        || methodKey.name().contains("jacoco$") // handled by InterfaceDesugaring.
        || methodKey.name().contains("$jacoco"); // handled by InterfaceDesugaring.
  }

  @Override
  public void visitNestHost(String nestHost) {
    isInNest = true;
    classAttributesBuilder.setNestHost(ClassName.create(nestHost));
    super.visitNestHost(nestHost);
  }

  @Override
  public void visitNestMember(String nestMember) {
    isInNest = true;
    classAttributesBuilder.addNestMember(ClassName.create(nestMember));
    super.visitNestMember(nestMember);
  }

  @Override
  public void visitEnd() {
    if (isInNest || (classAccessCode & Opcodes.ACC_INTERFACE) != 0) {
      memberRecord.mergeFrom(stagingMemberRecord);
    }
    classAttributeRecord.setClassAttributes(classAttributesBuilder.build());
    super.visitEnd();
  }

  /**
   * A visitor that collects privately referenced class members (fields/constructors/methods) within
   * a nest.
   */
  private static class CrossMateRefCollector extends MethodVisitor {

    /** The current enclosing the method. */
    private final MethodKey enclosingMethodKey;

    /**
     * A per-class class member record and will determined to merge or not into the main member
     * record at visitEnd of its associated class visitor.
     *
     * <p>@see CrossMateMainCollector#stagingMemberRecord for more details.
     */
    private final ClassMemberRecord memberRecord;

    CrossMateRefCollector(
        MethodVisitor methodVisitor, MethodKey enclosingMethodKey, ClassMemberRecord memberRecord) {
      super(Opcodes.ASM7, methodVisitor);
      this.enclosingMethodKey = enclosingMethodKey;
      this.memberRecord = memberRecord;
    }

    @Override
    public void visitFieldInsn(int opcode, String owner, String name, String descriptor) {
      FieldKey memberKey = FieldKey.create(ClassName.create(owner), name, descriptor);
      if (LangModelHelper.isCrossMateRefInNest(memberKey, enclosingMethodKey)) {
        memberRecord.logMemberUse(memberKey, opcode);
      }
      super.visitFieldInsn(opcode, owner, name, descriptor);
    }

    @Override
    public void visitMethodInsn(
        int opcode, String owner, String name, String descriptor, boolean isInterface) {
      MethodKey memberKey = MethodKey.create(ClassName.create(owner), name, descriptor);
      if (isInterface || LangModelHelper.isCrossMateRefInNest(memberKey, enclosingMethodKey)) {
        memberRecord.logMemberUse(memberKey, opcode);
      }
      super.visitMethodInsn(opcode, owner, name, descriptor, isInterface);
    }
  }
}
