/*
 * 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;

import com.google.gwt.core.ext.TreeLogger;
import com.google.gwt.core.ext.UnableToCompleteException;
import com.google.gwt.core.ext.linker.ModuleMetricsArtifact;
import com.google.gwt.core.ext.linker.PrecompilationMetricsArtifact;
import com.google.gwt.dev.CompilerContext;
import com.google.gwt.dev.Permutation;
import com.google.gwt.dev.PrecompileTaskOptions;
import com.google.gwt.dev.PrecompileTaskOptionsImpl;
import com.google.gwt.dev.jjs.ast.JProgram;
import com.google.gwt.dev.js.ast.JsProgram;
import com.google.gwt.dev.util.DiskCache;
import com.google.gwt.dev.util.Util;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.Collections;
import java.util.Set;
import java.util.SortedSet;
import java.util.TreeSet;

/**
 * Represents a unified, non-permutation specific AST. This AST is used to drive
 * per-permutation compiles.
 */
public class UnifiedAst implements Serializable {

  /**
   * Encapsulates the combined programs.
   */
  public static final class AST implements Serializable {
    private final JProgram jProgram;
    private final JsProgram jsProgram;

    public AST(JProgram jProgram, JsProgram jsProgram) {
      this.jProgram = jProgram;
      this.jsProgram = jsProgram;
    }

    public JProgram getJProgram() {
      return jProgram;
    }

    public JsProgram getJsProgram() {
      return jsProgram;
    }
  }

  private static final DiskCache diskCache = DiskCache.INSTANCE;

  /**
   * The original AST; nulled out once consumed (by the first call to
   * {@link #getFreshAst()}.
   */
  private transient AST initialAst;

  /**
   * Metrics for the module load phase. Stored here so they can be written out
   * as artifacts in the compile phase.
   */
  private ModuleMetricsArtifact moduleMetrics;

  /**
   * Used for internal synchronization.
   */
  private transient Object myLockObject = new Object();

  /**
   * The compilation options.
   */
  private final PrecompileTaskOptions options;

  /**
   * Metrics for the precompilation phase. Stored here so they can be written
   * out as artifacts in the compile phase.
   */
  private PrecompilationMetricsArtifact precompilationMetrics;

  /**
   * The set of all live rebind request types in the AST.
   */
  private final SortedSet<String> rebindRequests;

  /**
   * The serialized AST.
   */
  private transient long serializedAstToken;

  public UnifiedAst(PrecompileTaskOptions options, AST initialAst, boolean singlePermutation,
      Set<String> rebindRequests) {
    this.options = new PrecompileTaskOptionsImpl(options);
    this.initialAst = initialAst;
    this.rebindRequests = Collections.unmodifiableSortedSet(new TreeSet<String>(rebindRequests));
    this.serializedAstToken = singlePermutation ? -1 : diskCache.writeObject(initialAst);
  }

  /**
   * Compiles a particular permutation.
   *
   * @param logger the logger to use
   * @param compilerContext shared read only compiler state
   * @param permutation the permutation to compile
   * @return the permutation result
   * @throws UnableToCompleteException if an error other than
   *           {@link OutOfMemoryError} occurs
   */
  public PermutationResult compilePermutation(
      TreeLogger logger, CompilerContext compilerContext, Permutation permutation)
      throws UnableToCompleteException {
    JavaToJavaScriptCompiler javaToJavaScriptCompiler =
        new MonolithicJavaToJavaScriptCompiler(logger, compilerContext);
    return javaToJavaScriptCompiler.compilePermutation(this, permutation);
  }

  /**
   * Return the current AST so that clients can explicitly walk the Java or
   * JavaScript parse trees.
   *
   * @return the current AST object holding the Java and JavaScript trees.
   */
  public AST getFreshAst() {
    synchronized (myLockObject) {
      if (initialAst != null) {
        AST result = initialAst;
        initialAst = null;
        return result;
      } else {
        if (serializedAstToken < 0) {
          throw new IllegalStateException(
              "No serialized AST was cached and AST was already consumed.");
        }
        return diskCache.readObject(serializedAstToken, AST.class);
      }
    }
  }

  /**
   * Returns metrics about the module load portion of the build.
   */
  public ModuleMetricsArtifact getModuleMetrics() {
    return moduleMetrics;
  }

  /**
   * Returns the active set of JJS options associated with this compile.
   */
  public PrecompileTaskOptions getOptions() {
    return new PrecompileTaskOptionsImpl(options);
  }

  /**
   * Returns metrics about the precompilation portion of the build.
   */
  public PrecompilationMetricsArtifact getPrecompilationMetrics() {
    return precompilationMetrics;
  }

  /**
   * Returns the set of live rebind requests in the AST.
   */
  public SortedSet<String> getRebindRequests() {
    return rebindRequests;
  }

  /**
   * Internally prepares a new AST for compilation if one is not already
   * prepared.
   */
  public void prepare() {
    synchronized (myLockObject) {
      if (initialAst == null) {
        initialAst = diskCache.readObject(serializedAstToken, AST.class);
      }
    }
  }

  /**
   * Save some module load metrics in the AST.
   */
  public void setModuleMetrics(ModuleMetricsArtifact metrics) {
    this.moduleMetrics = metrics;
  }

  /**
   * Save some precompilation metrics in the AST.
   */
  public void setPrecompilationMetrics(PrecompilationMetricsArtifact metrics) {
    this.precompilationMetrics = metrics;
  }

  /**
   * Re-initialize lock object; copy serialized AST straight to cache.
   */
  private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException {
    stream.defaultReadObject();
    myLockObject = new Object();
    serializedAstToken = diskCache.transferFromStream(stream);
  }

  /**
   * Force byte serialization of AST before writing.
   */
  private void writeObject(ObjectOutputStream stream) throws IOException {
    stream.defaultWriteObject();
    if (serializedAstToken >= 0) {
      // Copy the bytes.
      diskCache.transferToStream(serializedAstToken, stream);
    } else if (initialAst != null) {
      // Serialize into raw bytes.
      Util.writeObjectToStream(stream, initialAst);
    } else {
      throw new IllegalStateException("No serialized AST was cached and AST was already consumed.");
    }
  }
}
