/*
 * Copyright 2009 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.asm;

import com.google.gwt.dev.javac.asm.CollectClassData.AnnotationEnum;
import com.google.gwt.dev.util.StringInterner;

import org.objectweb.asm.AnnotationVisitor;
import org.objectweb.asm.Opcodes;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Collects data from (possibly nested) annotations on a single entity.
 */
public class CollectAnnotationData extends AnnotationVisitor {

  /**
   * Holds annotation fields/values.
   */
  public static class AnnotationData {
    private final String desc;
    private final Map<String, Object> values = new HashMap<String, Object>();
    private final boolean visible;

    protected AnnotationData(String desc, boolean visible) {
      this.desc = StringInterner.get().intern(desc);
      this.visible = visible;
    }

    public void addValue(String name, Object value) {
      values.put(StringInterner.get().intern(name), value);
    }

    /**
     * @return the desc
     */
    public String getDesc() {
      return desc;
    }

    /**
     * @return the values
     */
    public Map<String, Object> getValues() {
      return values;
    }

    /**
     * @return the visible
     */
    public boolean isVisible() {
      return visible;
    }
  }

  /**
   * Collects data inside an array-valued annotation parameter.
   */
  public static class MyAnnotationArrayVisitor extends AnnotationVisitor {

    private final Callback<Object> callback;
    private final List<Object> values = new ArrayList<Object>();

    public MyAnnotationArrayVisitor(Callback<Object> callback) {
      super(Opcodes.ASM7);
      this.callback = callback;
    }

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

    @Override
    public AnnotationVisitor visitAnnotation(String name, String desc) {
      // TODO(jat): what should visible be set to?
      return new CollectAnnotationData(desc, true,
          new Callback<CollectAnnotationData.AnnotationData>() {
            @Override
            public void call(CollectAnnotationData.AnnotationData value) {
              values.add(value);
            }
          });
    }

    @Override
    public AnnotationVisitor visitArray(String name) {
      return new MyAnnotationArrayVisitor(new Callback<Object>() {
        @Override
        public void call(Object value) {
          values.add(value);
        }
      });
    }

    @Override
    public void visitEnd() {
      callback.call(values.toArray());
    }

    @Override
    public void visitEnum(String name, String desc, String value) {
      values.add(new AnnotationEnum(desc, value));
    }
  }

  /**
   * Generic callback type taking a parameter.
   *
   * @param <T> type of the argument to the callback
   */
  private interface Callback<T> {

    /**
     * Invoke the callback.
     *
     * @param value value to pass to the callback.
     */
    void call(T value);
  }

  private final CollectAnnotationData.AnnotationData annotation;
  private final Callback<CollectAnnotationData.AnnotationData> callback;

  /**
   * Construct the collector.
   *
   * @param desc class descriptor of the annotation class
   * @param visible true if the annotation is visible at runtime
   */
  public CollectAnnotationData(String desc, boolean visible) {
    this(desc, visible, null);
  }

  /**
   * Construct the collector.
   *
   * @param desc class descriptor of the annotation class
   * @param visible true if the annotation is visible at runtime
   * @param callback callback to be called when the annotation is finished
   */
  CollectAnnotationData(String desc, boolean visible,
      Callback<CollectAnnotationData.AnnotationData> callback) {
    super(Opcodes.ASM7);
    annotation = new AnnotationData(desc, visible);
    this.callback = callback;
  }

  /**
   * @return the annotation data
   */
  public AnnotationData getAnnotation() {
    return annotation;
  }

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

  @Override
  public AnnotationVisitor visitAnnotation(final String name, String desc) {
    // TODO(jat): what should visible be set to?
    return new CollectAnnotationData(desc, true,
        new Callback<CollectAnnotationData.AnnotationData>() {
          @Override
          public void call(CollectAnnotationData.AnnotationData value) {
            annotation.addValue(name, value);
          }
        });
  }

  @Override
  public AnnotationVisitor visitArray(final String name) {
    return new MyAnnotationArrayVisitor(new Callback<Object>() {

      /**
       * Called with an array of values.
       *
       * @param value
       */
      @Override
      public void call(Object value) {
        annotation.addValue(name, value);
      }
    });
  }

  @Override
  public void visitEnd() {
    if (callback != null) {
      callback.call(annotation);
    }
  }

  @Override
  public void visitEnum(String name, String desc, String value) {
    annotation.addValue(name, new AnnotationEnum(desc, value));
  }
}
