/*
 * Copyright 2008 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.jjs.impl;

import com.google.gwt.core.ext.GeneratorContext;
import com.google.gwt.core.ext.PropertyOracle;
import com.google.gwt.core.ext.TreeLogger;
import com.google.gwt.core.ext.UnableToCompleteException;
import com.google.gwt.dev.cfg.BindingProperty;
import com.google.gwt.dev.cfg.ConfigurationProperty;
import com.google.gwt.dev.cfg.StaticPropertyOracle;
import com.google.gwt.dev.javac.StandardGeneratorContext;
import com.google.gwt.dev.jdt.FindDeferredBindingSitesVisitor;

import java.io.PrintWriter;

/**
 * Generates code for loading an island. The pattern of generated classes is
 * more complicated than otherwise necessary so that the loader code is
 * precisely handled by TypeTightener and LivenessAnalyzer.
 * 
 * TODO(spoon) Remove this generator by making LivenessAnalyzer know about
 * runAsync and how it works.
 */
public class FragmentLoaderCreator {
  public static final String ASYNC_FRAGMENT_LOADER = "com.google.gwt.core.client.impl.AsyncFragmentLoader";
  public static final String ASYNC_LOADER_CLASS_PREFIX = "AsyncLoader";
  public static final String ASYNC_LOADER_PACKAGE = "com.google.gwt.lang.asyncloaders";
  public static final String BROWSER_LOADER = "AsyncFragmentLoader.BROWSER_LOADER";
  public static final String CALLBACK_LIST_SUFFIX = "__Callback";
  public static final String LOADER_METHOD_RUN_ASYNC = "runAsync";
  public static final String RUN_ASYNC_CALLBACK = "com.google.gwt.core.client.RunAsyncCallback";
  public static final String RUN_CALLBACKS = "runCallbacks";
  private static final String GWT_CLASS = FindDeferredBindingSitesVisitor.MAGIC_CLASS;
  private static final String PROP_RUN_ASYNC_NEVER_RUNS = "gwt.jjs.runAsyncNeverRuns";
  private static final String UNCAUGHT_EXCEPTION_HANDLER_CLASS = "GWT.UncaughtExceptionHandler";

  private final StandardGeneratorContext context;
  private int entryNumber = 0;
  private final PropertyOracle propOracle;

  /**
   * Construct a FragmentLoaderCreator. The reason it needs so many parameters
   * is that it uses generator infrastructure.
   */
  public FragmentLoaderCreator(StandardGeneratorContext context) {
    // An empty property oracle is fine, because fragment loaders aren't
    // affected by properties anyway
    this.propOracle = new StaticPropertyOracle(new BindingProperty[0],
        new String[0], new ConfigurationProperty[0]);
    this.context = context;
  }

  public String create(TreeLogger logger) throws UnableToCompleteException {
    // First entry is 1.
    ++entryNumber;
    context.setPropertyOracle(propOracle);
    PrintWriter loaderWriter = getSourceWriterForLoader(logger, context);
    if (loaderWriter == null) {
      logger.log(TreeLogger.ERROR, "Failed to create island loader named "
          + getLoaderQualifiedName());
      throw new UnableToCompleteException();
    }

    generateLoaderFields(loaderWriter);
    generateOnLoadMethod(loaderWriter);
    generateRunAsyncMethod(loaderWriter);
    generateRunCallbacksMethod(loaderWriter);
    generateRunCallbackOnFailuresMethod(loaderWriter);

    loaderWriter.println("}");
    loaderWriter.close();
    context.commit(logger, loaderWriter);

    writeCallbackListClass(logger, context);

    return getLoaderQualifiedName();
  }

  private void generateLoaderFields(PrintWriter srcWriter) {
    srcWriter.println("// Callbacks that are pending");
    srcWriter.println("private static " + getCallbackListSimpleName()
        + " callbacksHead = null;");

    srcWriter.println("// The tail of the callbacks list");
    srcWriter.println("private static " + getCallbackListSimpleName()
        + " callbacksTail = null;");

    srcWriter.println("// A callback caller for this entry point");
    srcWriter.println("private static " + getLoaderSimpleName()
        + " instance = null;");
  }

  private void generateOnLoadMethod(PrintWriter srcWriter) {
    srcWriter.println("public static void onLoad() {");
    srcWriter.println("instance = new " + getLoaderSimpleName() + "();");
    srcWriter.println(BROWSER_LOADER + ".fragmentHasLoaded(" + entryNumber
        + ");");

    srcWriter.println(BROWSER_LOADER + ".logEventProgress(\""
        + RUN_CALLBACKS + entryNumber + "\", \"begin\");");
    srcWriter.println("instance." + RUN_CALLBACKS + "();");
    srcWriter.println(BROWSER_LOADER + ".logEventProgress(\""
        + RUN_CALLBACKS + entryNumber + "\", \"end\");");

    srcWriter.println("}");
  }

  /**
   * Generate the <code>runAsync</code> method. Calls to
   * <code>GWT.runAsync</code> are replaced by calls to this method.
   */
  private void generateRunAsyncMethod(PrintWriter srcWriter) {
    srcWriter.println("public static void " + LOADER_METHOD_RUN_ASYNC
        + "(RunAsyncCallback callback) {");
    srcWriter.println(getCallbackListSimpleName() + " newCallback = new "
        + getCallbackListSimpleName() + "();");
    srcWriter.println("newCallback.callback = callback;");

    srcWriter.println("if (callbacksTail != null) {");
    srcWriter.println("  callbacksTail.next = newCallback;");
    srcWriter.println("}");

    srcWriter.println("callbacksTail = newCallback;");
    srcWriter.println("if (callbacksHead == null) {");
    srcWriter.println("  callbacksHead = newCallback;");
    srcWriter.println("}");

    srcWriter.println("if (instance != null) {");
    srcWriter.println("  instance." + RUN_CALLBACKS + "();");
    srcWriter.println("  return;");
    srcWriter.println("}");
    srcWriter.println("if (!" + BROWSER_LOADER + ".isLoading(" + entryNumber
        + ")) {");
    srcWriter.println("  " + BROWSER_LOADER + ".inject(" + entryNumber + ",");
    srcWriter.println("  new AsyncFragmentLoader.LoadTerminatedHandler() {");
    srcWriter.println("    public void loadTerminated(Throwable reason) {");
    srcWriter.println("      runCallbackOnFailures(reason);");
    srcWriter.println("    }");
    srcWriter.println("  });");
    srcWriter.println("}");
    srcWriter.println("}");
  }

  private void generateRunCallbackOnFailuresMethod(PrintWriter srcWriter) {
    srcWriter.println("private static void runCallbackOnFailures(Throwable e) {");
    srcWriter.println("while (callbacksHead != null) {");
    srcWriter.println("  callbacksHead.callback.onFailure(e);");
    srcWriter.println("  callbacksHead = callbacksHead.next;");
    srcWriter.println("}");
    srcWriter.println("callbacksTail = null;");
    srcWriter.println("}");
  }

  private void generateRunCallbacksMethod(PrintWriter srcWriter) {
    srcWriter.println("public void " + RUN_CALLBACKS + "() {");

    srcWriter.println("while (callbacksHead != null) {");

    srcWriter.println("  " + UNCAUGHT_EXCEPTION_HANDLER_CLASS + " handler = "
        + "GWT.getUncaughtExceptionHandler();");

    srcWriter.println("  " + getCallbackListSimpleName()
        + " next = callbacksHead;");
    srcWriter.println("  callbacksHead = callbacksHead.next;");
    srcWriter.println("  if (callbacksHead == null) {");
    srcWriter.println("    callbacksTail = null;");
    srcWriter.println("  }");

    if (!Boolean.getBoolean(PROP_RUN_ASYNC_NEVER_RUNS)) {
      // TODO(spoon): this runs the callbacks immediately; deferred would be
      // better
      srcWriter.println("  if (handler == null) {");
      srcWriter.println("    next.callback.onSuccess();");
      srcWriter.println("  } else {");
      srcWriter.println("    try {");
      srcWriter.println("      next.callback.onSuccess();");
      srcWriter.println("    } catch (Throwable e) {");
      srcWriter.println("      handler.onUncaughtException(e);");
      srcWriter.println("    }");
      srcWriter.println("  }");
    }

    srcWriter.println("}");
    srcWriter.println("}");
  }

  private String getCallbackListQualifiedName() {
    return ASYNC_LOADER_PACKAGE + getCallbackListSimpleName();
  }

  private String getCallbackListSimpleName() {
    return getLoaderSimpleName() + CALLBACK_LIST_SUFFIX;
  }

  private String getLoaderQualifiedName() {
    return ASYNC_LOADER_PACKAGE + "." + getLoaderSimpleName();
  }

  private String getLoaderSimpleName() {
    return ASYNC_LOADER_CLASS_PREFIX + entryNumber;
  }

  private String getPackage() {
    return ASYNC_LOADER_PACKAGE;
  }

  private PrintWriter getSourceWriterForLoader(TreeLogger logger,
      GeneratorContext ctx) {
    PrintWriter printWriter = ctx.tryCreate(logger, getPackage(),
        getLoaderSimpleName());
    if (printWriter == null) {
      return null;
    }

    printWriter.println("package " + getPackage() + ";");
    String[] imports = new String[] {
        GWT_CLASS, RUN_ASYNC_CALLBACK, ASYNC_FRAGMENT_LOADER};
    for (String imp : imports) {
      printWriter.println("import " + imp + ";");
    }

    printWriter.println("public class " + getLoaderSimpleName() + " {");
    return printWriter;
  }

  private void writeCallbackListClass(TreeLogger logger, GeneratorContext ctx)
      throws UnableToCompleteException {
    PrintWriter printWriter = ctx.tryCreate(logger, getPackage(),
        getCallbackListSimpleName());
    if (printWriter == null) {
      logger.log(TreeLogger.ERROR, "Could not create type: "
          + getCallbackListQualifiedName());
      throw new UnableToCompleteException();
    }

    printWriter.println("package " + getPackage() + ";");
    printWriter.println("public class " + getCallbackListSimpleName() + "{");
    printWriter.println(RUN_ASYNC_CALLBACK + " callback;");
    printWriter.println(getCallbackListSimpleName() + " next;");
    printWriter.println("}");

    printWriter.close();
    ctx.commit(logger, printWriter);
  }
}
