/*
 * 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.web.bindery.requestfactory.apt;

import static com.google.web.bindery.requestfactory.vm.impl.TypeTokenResolver.TOKEN_MANIFEST;

import com.google.web.bindery.requestfactory.shared.BaseProxy;
import com.google.web.bindery.requestfactory.vm.impl.OperationKey;
import com.google.web.bindery.requestfactory.vm.impl.TypeTokenResolver;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.Map;
import java.util.Set;

import javax.annotation.processing.AbstractProcessor;
import javax.annotation.processing.Filer;
import javax.annotation.processing.FilerException;
import javax.annotation.processing.ProcessingEnvironment;
import javax.annotation.processing.RoundEnvironment;
import javax.annotation.processing.SupportedAnnotationTypes;
import javax.annotation.processing.SupportedOptions;
import javax.annotation.processing.SupportedSourceVersion;
import javax.lang.model.SourceVersion;
import javax.lang.model.element.Element;
import javax.lang.model.element.TypeElement;
import javax.lang.model.type.TypeMirror;
import javax.lang.model.util.ElementFilter;
import javax.lang.model.util.ElementScanner6;
import javax.lang.model.util.Elements;
import javax.lang.model.util.Types;
import javax.tools.Diagnostic.Kind;
import javax.tools.FileObject;
import javax.tools.JavaFileObject;
import javax.tools.StandardLocation;

/**
 * An annotation processor that creates an obfuscated type manifest that is used
 * by {@link com.google.web.bindery.requestfactory.vm.RequestFactorySource} and
 * related implementation classes.
 */
@SupportedAnnotationTypes("com.google.web.bindery.requestfactory.*")
@SupportedSourceVersion(SourceVersion.RELEASE_6)
@SupportedOptions("verbose")
public class RfApt extends AbstractProcessor {

  /**
   * Looks for all types assignable to {@link BaseProxy} and adds them to the
   * output state.
   */
  private class Finder extends ElementScanner6<Void, Void> {
    // Only valid for a single round
    TypeMirror baseProxyType = elements.getTypeElement(BaseProxy.class.getCanonicalName()).asType();

    @Override
    public Void visitType(TypeElement elt, Void arg1) {
      String binaryName = elements.getBinaryName(elt).toString();
      if (types.isSubtype(elt.asType(), baseProxyType)) {
        String hash = OperationKey.hash(binaryName);
        builder.addTypeToken(hash, binaryName);
        log(elt, "Processed proxy %s %s", binaryName, hash);
      }
      return super.visitType(elt, arg1);
    }
  }

  private TypeTokenResolver.Builder builder;
  private Elements elements;
  private Filer filer;
  private boolean verbose;
  private Types types;

  @Override
  public synchronized void init(ProcessingEnvironment processingEnv) {
    super.init(processingEnv);
    log("RfApt init");
    elements = processingEnv.getElementUtils();
    filer = processingEnv.getFiler();
    types = processingEnv.getTypeUtils();
    verbose = Boolean.parseBoolean(processingEnv.getOptions().get("verbose"));
  }

  @Override
  public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
    log("RequestFactory processing a round");

    if (builder == null) {
      builder = new TypeTokenResolver.Builder();
      // Try not to obliterate existing data
      try {
        FileObject resource = filer.getResource(StandardLocation.CLASS_OUTPUT, "", TOKEN_MANIFEST);
        builder.load(resource.openInputStream());
        log("Reusing old data");
      } catch (IOException e) {
        // Likely because the file does not exist
        log("Not reusing existing manifest file: " + e.getMessage());
      }
    }

    // Extract data
    new Finder().scan(ElementFilter.typesIn(roundEnv.getRootElements()), null);

    // On the last round, write out accumulated data
    if (roundEnv.processingOver()) {
      TypeTokenResolver d = builder.build();
      builder = null;
      try {
        FileObject res = filer.createResource(StandardLocation.CLASS_OUTPUT, "", TOKEN_MANIFEST);
        d.store(res.openOutputStream());
      } catch (IOException e) {
        error("Could not write output: " + e.getMessage());
      }

      /*
       * Getting the TOKEN_MANIFEST resource into an Android APK generated by
       * the Android Eclipse plugin is non-trivial. (Users of ant and apkbuilder
       * can just use -rf to include the relevant file). To support the common
       * use-case, we'll generate a subclass of TypeTokenResolver.Builder that
       * has all of the data already baked into it. This synthetic subtype is
       * looked for first by TypeTokenResolver and any manifests that are on the
       * classpath will be added on top.
       */
      try {
        String packageName = TypeTokenResolver.class.getPackage().getName();
        String simpleName = TypeTokenResolver.class.getSimpleName() + "BuilderImpl";
        JavaFileObject classfile = filer.createSourceFile(packageName + "." + simpleName);
        PrintWriter pw = new PrintWriter(classfile.openWriter());
        pw.println("package " + packageName + ";");
        pw.println("public class " + simpleName + " extends "
            + TypeTokenResolver.Builder.class.getCanonicalName() + " {");
        pw.println("public " + simpleName + "() {");
        for (Map.Entry<String, String> entry : d.getAllTypeTokens().entrySet()) {
          if (elements.getTypeElement(entry.getValue()) != null) {
            pw.println("addTypeToken(\"" + entry.getKey() + "\", " + entry.getValue()
                + ".class.getName());");
          }
        }
        pw.println("}");
        pw.println("}");
        pw.close();
      } catch (FilerException e) {
        log("Ignoring exception: %s", e.getMessage());
      } catch (IOException e) {
        error("Could not write BuilderImpl: " + e.getMessage());
      }
      log("Finished!");
    }
    return false;
  }

  private void error(String message, Object... args) {
    processingEnv.getMessager().printMessage(Kind.ERROR, "ERROR: " + String.format(message, args));
  }

  private void log(Element elt, String message, Object... args) {
    if (verbose) {
      processingEnv.getMessager().printMessage(Kind.NOTE, String.format(message, args), elt);
    }
  }

  private void log(String message, Object... args) {
    if (verbose) {
      processingEnv.getMessager().printMessage(Kind.NOTE, String.format(message, args));
    }
  }
}
