/*
 * Copyright 2014-present Facebook, Inc.
 *
 * 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.facebook.buck.java.abi;

import com.google.common.base.Preconditions;
import com.google.common.base.Strings;
import com.google.common.collect.ComparisonChain;
import com.google.common.collect.Sets;
import com.google.common.io.ByteSource;

import org.objectweb.asm.AnnotationVisitor;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.FieldVisitor;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;

import java.io.IOException;
import java.util.SortedSet;
import java.util.jar.JarEntry;
import java.util.jar.JarOutputStream;

import javax.annotation.Nullable;

class ClassMirror extends ClassVisitor implements Comparable<ClassMirror> {

  private final String fileName;
  private final SortedSet<AnnotationMirror> annotations;
  private final SortedSet<FieldMirror> fields;
  private final SortedSet<InnerClass> innerClasses;
  private final SortedSet<MethodMirror> methods;
  @Nullable
  private OuterClass outerClass;
  private int version;
  private int access;
  @Nullable
  private String signature;
  @Nullable
  private String[] interfaces;
  @Nullable
  private String superName;
  @Nullable
  private String name;

  public ClassMirror(String name) {
    super(Opcodes.ASM5);

    this.fileName = name;
    this.annotations = Sets.newTreeSet();
    this.fields = Sets.newTreeSet();
    this.innerClasses = Sets.newTreeSet();
    this.methods = Sets.newTreeSet();
  }

  @Override
  public void visit(
      int version,
      int access,
      String name,
      String signature,
      String superName,
      String[] interfaces) {
    this.name = name;
    this.version = version;
    this.access = access;
    this.signature = signature;
    this.interfaces = interfaces;
    this.superName = superName;
  }

  @Override
  public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
    AnnotationMirror mirror = new AnnotationMirror(desc, visible);
    annotations.add(mirror);
    return mirror;
  }

  @Override
  public FieldVisitor visitField(
      int access,
      String name,
      String desc,
      String signature,
      Object value) {
    if ((access & Opcodes.ACC_PRIVATE) > 0) {
      return super.visitField(access, name, desc, signature, value);
    }

    FieldMirror mirror = new FieldMirror(access, name, desc, signature, value);
    fields.add(mirror);
    return mirror;
  }

  @Override
  public MethodVisitor visitMethod(
      int access, String name, String desc, String signature, String[] exceptions) {

    if ((access & Opcodes.ACC_PRIVATE) > 0) {
      return super.visitMethod(access, name, desc, signature, exceptions);
    }

    // Bridge methods are created by the compiler, and don't appear in source. It would be nice to
    // skip them, but they're used by the compiler to cover the fact that type erasure has occurred.
    // Normally the compiler adds these as public methods, but if you're compiling against a stub
    // produced using our ABI generator, we don't want people calling it accidentally. Oh well, I
    // guess it happens IRL too.
    //
    // Synthetic methods are also generated by the compiler, unless it's one of the methods named in
    // section 4.7.8 of the JVM spec, which are "<init>" and "Enum.valueOf()" and "Enum.values".
    // None of these are actually harmful to the ABI, so we allow synthetic methods through.
    // http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html#jvms-4.7.8
    MethodMirror mirror = new MethodMirror(access, name, desc, signature, exceptions);
    methods.add(mirror);

    return mirror;
  }

  @Override
  public void visitOuterClass(String owner, String name, String desc) {
    outerClass = new OuterClass(owner, name, desc);
    super.visitOuterClass(owner, name, desc);
  }

  @Override
  public void visitInnerClass(String name, String outerName, String innerName, int access) {
    if ((access & Opcodes.ACC_PRIVATE) > 0) {
      return;
    }

    innerClasses.add(new InnerClass(name, outerName, innerName, access));
    super.visitInnerClass(name, outerName, innerName, access);
  }

  @Override
  public int compareTo(ClassMirror o) {
    return fileName.compareTo(o.fileName);
  }

  public void writeTo(JarOutputStream jar) throws IOException {
    JarEntry entry = new JarEntry(fileName);
    entry.setTime(0);

    jar.putNextEntry(entry);
    ClassWriter writer = new ClassWriter(0);
    writer.visit(version, access, name, signature, superName, interfaces);

    if (outerClass != null) {
      writer.visitOuterClass(outerClass.owner, outerClass.name, outerClass.desc);
    }

    for (InnerClass inner : innerClasses) {
      writer.visitInnerClass(inner.name, inner.outerName, inner.innerName, inner.access);
    }

    for (AnnotationMirror annotation : annotations) {
      annotation.appendTo(writer);
    }

    for (FieldMirror field : fields) {
      field.accept(writer);
    }

    for (MethodMirror method : methods) {
      method.appendTo(writer);
    }
    writer.visitEnd();
    ByteSource.wrap(writer.toByteArray()).copyTo(jar);
    jar.closeEntry();
  }

  private static class InnerClass implements Comparable<InnerClass> {

    private final String name;
    @Nullable
    private final String outerName;
    @Nullable
    private final String innerName;
    private final int access;

    public InnerClass(
        String name,
        @Nullable String outerName,
        @Nullable String innerName,
        int access) {
      this.name = name;
      this.outerName = outerName;
      this.innerName = innerName;
      this.access = access;
    }

    @Override
    public int compareTo(InnerClass o) {
      Preconditions.checkNotNull(o);
      return ComparisonChain.start()
          .compare(name, o.name)
          .compare(Strings.nullToEmpty(outerName), Strings.nullToEmpty(o.outerName))
          .compare(Strings.nullToEmpty(innerName), Strings.nullToEmpty(o.innerName))
          .result();
    }
  }

  private static class OuterClass implements Comparable<OuterClass> {

    private final String owner;
    private final String name;
    private final String desc;

    public OuterClass(String owner, String name, String desc) {
      this.owner = owner;
      this.name = name;
      this.desc = desc;
    }

    @Override
    public int compareTo(OuterClass o) {
      Preconditions.checkNotNull(o);
      return ComparisonChain.start()
          .compare(owner, o.owner)
          .compare(name, o.name)
          .compare(desc, o.desc)
          .result();
    }
  }
}
