/*
 * Copyright 2011 Google 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.google.gwt.dev.javac;

import com.google.gwt.dev.asm.AnnotationVisitor;
import com.google.gwt.dev.asm.Attribute;
import com.google.gwt.dev.asm.ClassReader;
import com.google.gwt.dev.asm.ClassVisitor;
import com.google.gwt.dev.asm.FieldVisitor;
import com.google.gwt.dev.asm.MethodVisitor;
import com.google.gwt.dev.asm.Opcodes;
import com.google.gwt.dev.util.Util;

import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

/**
 * Creates string hashes for various purposes from walking bytecode.
 */
public class BytecodeSignatureMaker {

  /**
   * This visitor looks at methods and members to compute a signature. This is
   * intended for determining if a type needs to be recompiled if byte code it
   * depends on changes.
   * 
   * At first, you'd think only public and protected members should be
   * considered, but the JSNI violator pattern means that even a change in a
   * private member might invalidate an access from another class.
   */
  private static class CompileDependencyVisitor implements ClassVisitor {
    /**
     * Mask to strip access bits we don't care about for computing the
     * signature.
     */
    private static final int ACCESS_FILTER_MASK =
        ~(Opcodes.ACC_DEPRECATED | Opcodes.ACC_NATIVE | Opcodes.ACC_STRICT
            | Opcodes.ACC_SYNCHRONIZED | Opcodes.ACC_SUPER | Opcodes.ACC_TRANSIENT | Opcodes.ACC_VOLATILE);

    private String header;
    private Map<String, String> fields = new HashMap<String, String>();
    private Map<String, String> methods = new HashMap<String, String>();

    public String getSignature() {
      return Util.computeStrongName(Util.getBytes(getRawString()));
    }

    public void visit(int version, int access, String name, String signature, String superName,
        String[] interfaces) {
      StringBuilder headerBuilder = new StringBuilder();
      // ignoring version
      headerBuilder.append(access & ACCESS_FILTER_MASK);
      headerBuilder.append(":");
      headerBuilder.append(name);
      if (signature != null) {
        headerBuilder.append(":");
        headerBuilder.append(signature);
      }
      if (superName != null) {
        headerBuilder.append(":");
        headerBuilder.append(superName);
      }
      if (interfaces != null) {
        Arrays.sort(interfaces);
        for (String iface : interfaces) {
          headerBuilder.append(":");
          headerBuilder.append(iface);
        }
      }
      header = headerBuilder.toString();
    }

    public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
      // ignore
      return null;
    }

    public void visitAttribute(Attribute attr) {
      // ignore
    }

    public void visitEnd() {
      // unused
    }

    public FieldVisitor visitField(int access, String name, String desc, String signature,
        Object value) {
      StringBuilder fieldBuilder = new StringBuilder();
      // We don't care about synthetic fields
      if ((access & (Opcodes.ACC_SYNTHETIC)) == 0) {
        fieldBuilder.append(access & ACCESS_FILTER_MASK);
        fieldBuilder.append(":");
        fieldBuilder.append(name);
        fieldBuilder.append(":");
        fieldBuilder.append(desc);
        if (signature != null) {
          fieldBuilder.append(":");
          fieldBuilder.append(signature);
        }
        if (value != null) {
          fieldBuilder.append(":");
          fieldBuilder.append(value.toString());
        }
        fields.put(name, fieldBuilder.toString());
      }

      // ignoring annotations/attributes on the field.
      return null;
    }

    public void visitInnerClass(String name, String outerName, String innerName, int access) {
      // ignored
    }

    public MethodVisitor visitMethod(int access, String name, String desc, String signature,
        String[] exceptions) {
      // We don't care about synthetic methods
      if ((access & (Opcodes.ACC_SYNTHETIC)) == 0) {
        StringBuilder methodBuilder = new StringBuilder();
        methodBuilder.append(access & ACCESS_FILTER_MASK);
        methodBuilder.append(":");
        methodBuilder.append(name);
        methodBuilder.append(":");
        methodBuilder.append(desc);
        if (signature != null) {
          methodBuilder.append(":");
          methodBuilder.append(signature);
        }
        if (exceptions != null) {
          String[] sortedExceptions = exceptions;
          Arrays.sort(sortedExceptions);
          for (String exception : sortedExceptions) {
            methodBuilder.append(":");
            methodBuilder.append(exception);
          }
        }
        methods.put(name, methodBuilder.toString());
      }
      return null;
    }

    public void visitOuterClass(String owner, String name, String desc) {
      // ignored
    }

    public void visitSource(String source, String debug) {
      // ignore
    }

    private String getRawString() {
      StringBuilder signatureBuilder = new StringBuilder();
      signatureBuilder.append(header);
      signatureBuilder.append("|");

      // sort all fields and methods for a deterministic signature.
      String[] sortedFields = fields.values().toArray(new String[0]);
      Arrays.sort(sortedFields);
      for (String field : sortedFields) {
        signatureBuilder.append(field);
        signatureBuilder.append("|");
      }

      String[] sortedMethods = methods.values().toArray(new String[0]);
      Arrays.sort(sortedMethods);
      for (String method : sortedMethods) {
        signatureBuilder.append(method);
        signatureBuilder.append("|");
      }
      return signatureBuilder.toString();
    }
  }

  /**
   * Returns a hash computed from the non-private/non-synthetic members and
   * methods in a class.
   * 
   * @param byteCode byte code for class to analyze.
   * @return a hex string representing an MD5 digest.
   */
  public static String getCompileDependencySignature(byte[] byteCode) {
    CompileDependencyVisitor v = visitCompileDependenciesInBytecode(byteCode);
    return v.getSignature();
  }

  /**
   * Returns a raw string used to compute the hash from the
   * non-synthetic members and methods in a class.
   * 
   * @param byteCode byte code for class to analyze.
   * @return a human readable string of all public API fields
   */
  static String getCompileDependencyRawSignature(byte[] byteCode) {
    CompileDependencyVisitor v = visitCompileDependenciesInBytecode(byteCode);
    return v.getRawString();
  }

  private static CompileDependencyVisitor visitCompileDependenciesInBytecode(byte[] byteCode) {
    ClassReader reader = new ClassReader(byteCode);
    CompileDependencyVisitor v = new CompileDependencyVisitor();
    reader.accept(v, ClassReader.SKIP_CODE | ClassReader.SKIP_DEBUG | ClassReader.SKIP_FRAMES);
    return v;
  }

  private BytecodeSignatureMaker() {
  }
}
