// Copyright (c) 2022, 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.keepanno.asm;

import com.android.tools.r8.keepanno.ast.AnnotationConstants;
import com.android.tools.r8.keepanno.ast.AnnotationConstants.Condition;
import com.android.tools.r8.keepanno.ast.AnnotationConstants.Edge;
import com.android.tools.r8.keepanno.ast.AnnotationConstants.Item;
import com.android.tools.r8.keepanno.ast.AnnotationConstants.Target;
import com.android.tools.r8.keepanno.ast.KeepClassReference;
import com.android.tools.r8.keepanno.ast.KeepConsequences;
import com.android.tools.r8.keepanno.ast.KeepEdge;
import com.android.tools.r8.keepanno.ast.KeepEdgeException;
import com.android.tools.r8.keepanno.ast.KeepFieldNamePattern.KeepFieldNameExactPattern;
import com.android.tools.r8.keepanno.ast.KeepFieldPattern;
import com.android.tools.r8.keepanno.ast.KeepItemPattern;
import com.android.tools.r8.keepanno.ast.KeepMemberPattern;
import com.android.tools.r8.keepanno.ast.KeepMethodNamePattern.KeepMethodNameExactPattern;
import com.android.tools.r8.keepanno.ast.KeepMethodPattern;
import com.android.tools.r8.keepanno.ast.KeepPreconditions;
import com.android.tools.r8.keepanno.ast.KeepQualifiedClassNamePattern;
import com.android.tools.r8.keepanno.utils.Unimplemented;
import java.util.function.BiFunction;
import org.objectweb.asm.AnnotationVisitor;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.Type;

public class KeepEdgeWriter implements Opcodes {

  /** Annotation visitor interface to allow usage from tests without type conflicts in r8lib. */
  public interface AnnotationVisitorInterface {
    int version();

    void visit(String name, Object value);

    void visitEnum(String name, String descriptor, String value);

    AnnotationVisitorInterface visitAnnotation(String name, String descriptor);

    AnnotationVisitorInterface visitArray(String name);

    void visitEnd();
  }

  private static AnnotationVisitor wrap(AnnotationVisitorInterface visitor) {
    if (visitor == null) {
      return null;
    }
    return new AnnotationVisitor(visitor.version()) {

      @Override
      public void visit(String name, Object value) {
        visitor.visit(name, value);
      }

      @Override
      public void visitEnum(String name, String descriptor, String value) {
        visitor.visitEnum(name, descriptor, value);
      }

      @Override
      public AnnotationVisitor visitAnnotation(String name, String descriptor) {
        AnnotationVisitorInterface v = visitor.visitAnnotation(name, descriptor);
        return v == visitor ? this : wrap(v);
      }

      @Override
      public AnnotationVisitor visitArray(String name) {
        AnnotationVisitorInterface v = visitor.visitArray(name);
        return v == visitor ? this : wrap(v);
      }

      @Override
      public void visitEnd() {
        visitor.visitEnd();
      }
    };
  }

  public static void writeEdge(KeepEdge edge, ClassVisitor visitor) {
    writeEdgeInternal(edge, visitor::visitAnnotation);
  }

  public static void writeEdge(
      KeepEdge edge, BiFunction<String, Boolean, AnnotationVisitorInterface> getVisitor) {
    writeEdgeInternal(edge, (descriptor, visible) -> wrap(getVisitor.apply(descriptor, visible)));
  }

  public static void writeEdgeInternal(
      KeepEdge edge, BiFunction<String, Boolean, AnnotationVisitor> getVisitor) {
    new KeepEdgeWriter().writeEdge(edge, getVisitor.apply(Edge.DESCRIPTOR, false));
  }

  private void writeEdge(KeepEdge edge, AnnotationVisitor visitor) {
    writePreconditions(visitor, edge.getPreconditions());
    writeConsequences(visitor, edge.getConsequences());
    visitor.visitEnd();
  }

  private void writePreconditions(AnnotationVisitor visitor, KeepPreconditions preconditions) {
    if (preconditions.isAlways()) {
      return;
    }
    String ignoredArrayValueName = null;
    AnnotationVisitor arrayVisitor = visitor.visitArray(Edge.preconditions);
    preconditions.forEach(
        condition -> {
          AnnotationVisitor conditionVisitor =
              arrayVisitor.visitAnnotation(ignoredArrayValueName, Condition.DESCRIPTOR);
          if (condition.getItem().isBindingReference()) {
            throw new Unimplemented();
          }
          writeItem(conditionVisitor, condition.getItem().asItemPattern());
        });
    arrayVisitor.visitEnd();
  }

  private void writeConsequences(AnnotationVisitor visitor, KeepConsequences consequences) {
    assert !consequences.isEmpty();
    String ignoredArrayValueName = null;
    AnnotationVisitor arrayVisitor = visitor.visitArray(Edge.consequences);
    consequences.forEachTarget(
        target -> {
          AnnotationVisitor targetVisitor =
              arrayVisitor.visitAnnotation(ignoredArrayValueName, Target.DESCRIPTOR);
          // No options imply keep all.
          if (!target.getOptions().isKeepAll()) {
            throw new Unimplemented();
          }
          if (target.getItem().isBindingReference()) {
            throw new Unimplemented();
          }
          writeItem(targetVisitor, target.getItem().asItemPattern());
        });
    arrayVisitor.visitEnd();
  }

  private void writeItem(AnnotationVisitor itemVisitor, KeepItemPattern item) {
    if (item.isAny(
        binding -> {
          throw new Unimplemented();
        })) {
      throw new Unimplemented();
    }
    KeepClassReference classReference = item.getClassReference();
    if (classReference.isBindingReference()) {
      throw new Unimplemented();
    }
    KeepQualifiedClassNamePattern namePattern = classReference.asClassNamePattern();
    if (namePattern.isExact()) {
      Type typeConstant = Type.getType(namePattern.getExactDescriptor());
      itemVisitor.visit(AnnotationConstants.Item.classConstant, typeConstant);
    } else {
      throw new Unimplemented();
    }
    if (!item.getExtendsPattern().isAny()) {
      throw new Unimplemented();
    }
    writeMember(item.getMemberPattern(), itemVisitor);
    itemVisitor.visitEnd();
  }

  private void writeMember(KeepMemberPattern memberPattern, AnnotationVisitor targetVisitor) {
    if (memberPattern.isNone()) {
      // Default is "no methods".
      return;
    }
    if (memberPattern.isAllMembers()) {
      throw new Unimplemented();
    }
    if (memberPattern.isMethod()) {
      writeMethod(memberPattern.asMethod(), targetVisitor);
    } else if (memberPattern.isField()) {
      writeField(memberPattern.asField(), targetVisitor);
    } else {
      throw new KeepEdgeException("Unexpected member pattern: " + memberPattern);
    }
  }

  private void writeField(KeepFieldPattern field, AnnotationVisitor targetVisitor) {
    KeepFieldNameExactPattern exactFieldName = field.getNamePattern().asExact();
    if (exactFieldName != null) {
      targetVisitor.visit(Item.fieldName, exactFieldName.getName());
    } else {
      throw new Unimplemented();
    }
    if (!field.getAccessPattern().isAny()) {
      throw new Unimplemented();
    }
    if (!field.getTypePattern().isAny()) {
      throw new Unimplemented();
    }
  }

  private void writeMethod(KeepMethodPattern method, AnnotationVisitor targetVisitor) {
    KeepMethodNameExactPattern exactMethodName = method.getNamePattern().asExact();
    if (exactMethodName != null) {
      targetVisitor.visit(Item.methodName, exactMethodName.getName());
    } else {
      throw new Unimplemented();
    }
    if (!method.getAccessPattern().isAny()) {
      throw new Unimplemented();
    }
    if (!method.getReturnTypePattern().isAny()) {
      if (exactMethodName != null
          && (exactMethodName.getName().equals("<init>")
              || exactMethodName.getName().equals("<clinit>"))
          && method.getReturnTypePattern().isVoid()) {
        // constructors have implicit void return.
      } else {
        throw new Unimplemented();
      }
    }
    if (!method.getParametersPattern().isAny()) {
      throw new Unimplemented();
    }
  }
}
