// Copyright 2015 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.

import org.objectweb.asm.AnnotationVisitor;
import org.objectweb.asm.Attribute;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.FieldVisitor;
import org.objectweb.asm.Label;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;

import java.util.ArrayList;
import java.util.List;

/**
 * A {@code ClassVisitor} that checks that ijar did its job.
 */
final class StripVerifyingVisitor extends ClassVisitor {
  public List<String> errors = new ArrayList<String>();
  private String className;

  public StripVerifyingVisitor() {
    super(Opcodes.ASM4);
  }

  @Override public void visit(
      int version,
      int access,
      String name,
      String signature,
      String superName,
      String[] interfaces) {
    className = name;
    if ((access & Opcodes.ACC_PRIVATE) != 0) {
      errors.add(String.format("Private class found %s", className));
    }
  }

  @Override public void visitSource(String source, String debug) {
    errors.add(String.format("Source entry found %s %s", source, debug));
  }

  @Override public void visitOuterClass(String owner, String name, String desc) {
    // Always okay.
  }

  @Override public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
    // Always okay.
    return null;
  }

  @Override public void visitAttribute(Attribute attr) {
    // Just assume this is okay.
  }

  @Override public void visitInnerClass(
      String name,
      String outerName,
      String innerName,
      int access) {
    // Always okay
    // TODO(bazel-team): verify removal of leftover inner classes once implemented
    // TODO(bazel-team): verify removal of private inner classes once implemented
  }

  @Override public FieldVisitor visitField(
      int access,
      String name,
      String desc,
      String signature,
      Object value) {
    if ((access & Opcodes.ACC_PRIVATE) != 0) {
      errors.add(String.format("Private field %s found in %s", name, className));
    }
    // We need to go deeper.
    return new StripVerifyingFieldVisitor(errors, className, name);
  }

  @Override public MethodVisitor visitMethod(
      int access,
      String name,
      String desc,
      String signature,
      String[] exceptions) {
    if ((access & Opcodes.ACC_PRIVATE) != 0) {
      errors.add(String.format("Private method %s found in %s", name, className));
    }
    // We need to go deeper.
    return new StripVerifyingMethodVisitor(errors, className, name);
  }

  @Override public void visitEnd() {
    // Always okay.
  }

  private static class StripVerifyingFieldVisitor extends FieldVisitor {
    private final List<String> errors;
    private final String className;
    private final String fieldName;

    StripVerifyingFieldVisitor(List<String> errors, String className, String fieldName) {
      super(Opcodes.ASM4);
      this.errors = errors;
      this.className = className;
      this.fieldName = fieldName;
    }

    @Override public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
      // Always okay.
      return null;
    }

    @Override public void visitAttribute(Attribute attr) {
      // Just assume this is okay.
    }

    @Override public void visitEnd() {
      // Always okay.
    }
  }

  private static class StripVerifyingMethodVisitor extends MethodVisitor {
    private final List<String> errors;
    private final String className;
    private final String methodName;

    StripVerifyingMethodVisitor(List<String> errors, String className, String methodName) {
      super(Opcodes.ASM4);
      this.errors = errors;
      this.className = className;
      this.methodName = methodName;
    }

    @Override public AnnotationVisitor visitAnnotationDefault() {
      // Always okay.
      return null;
    }

    @Override public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
      // Always okay.
      return null;
    }

    @Override public AnnotationVisitor visitParameterAnnotation(
        int parameter,
        String desc,
        boolean visible) {
      // Always okay.
      return null;
    }

    @Override public void visitAttribute(Attribute attr) {
      // Just assume this is okay.
    }

    @Override public void visitCode() {
      errors.add(String.format("Code found for method %s of %s", methodName, className));
    }

    @Override public void visitEnd() {}

    // We ignore all details about code segments. Presumably we already logged an error about code
    // existing at all.

    @Override public void visitFrame(
        int type,
        int nLocal,
        Object[] local,
        int nStack,
        Object[] stack) {}

    @Override public void visitInsn(int opcode) {}

    @Override public void visitIntInsn(int opcode, int operand) {}

    @Override public void visitVarInsn(int opcode, int var) {}

    @Override public void visitTypeInsn(int opcode, String type) {}

    @Override public void visitFieldInsn(int opcode, String owner, String name, String desc) {}

    @Override public void visitMethodInsn(int opcode, String owner, String name, String desc) {}

    @Override public void visitJumpInsn(int opcode, Label label) {}

    @Override public void visitLabel(Label label) {}

    @Override public void visitLdcInsn(Object cst) {}

    @Override public void visitIincInsn(int var, int increment) {}

    @Override public void visitTableSwitchInsn(int min, int max, Label dflt, Label... labels) {}

    @Override public void visitLookupSwitchInsn(Label dflt, int[] keys, Label[] labels) {}

    @Override public void visitMultiANewArrayInsn(String desc, int dims) {}

    @Override public void visitTryCatchBlock(Label start, Label end, Label handler, String type) {}

    @Override public void visitLocalVariable(
        String name,
        String desc,
        String signature,
        Label start,
        Label end,
        int index) {}

    @Override public void visitLineNumber(int line, Label start) {}

    @Override public void visitMaxs(int maxStack, int maxLocals) {}
  }
}
