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

import com.google.gwt.core.ext.TreeLogger;
import com.google.gwt.core.ext.TreeLogger.Type;
import com.google.gwt.core.ext.linker.ArtifactSet;
import com.google.gwt.core.ext.linker.EmittedArtifact;
import com.google.gwt.core.ext.linker.EmittedArtifact.Visibility;
import com.google.gwt.dev.jjs.UnifiedAst;
import com.google.gwt.dev.util.Util;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.Collection;

/**
 * The result of compilation phase 1, includes a unified AST and metadata
 * relevant to each permutation.
 */
public class Precompilation implements PrecompilationResult {
  /*
   * TODO: don't make this whole class serializable, instead dump the
   * independent members out to a file so that the generated artifacts are
   * optional to deserialize.
   */
  private transient ArtifactSet generatedArtifacts;
  private transient byte[] generatedArtifactsSerialized;
  private final Permutation[] permutations;
  private final UnifiedAst unifiedAst;

  /**
   * Constructs a new precompilation. We create new Permutations with a new id
   * so that the ids are consecutive and correspond to the index in the array.
   *
   * @param unifiedAst the unified AST used by
   *          {@link com.google.gwt.dev.jjs.JavaToJavaScriptCompiler}
   * @param permutations the set of permutations that can be run
   * @param permutationBase the id to use for the first permutation
   * @param generatedArtifacts the set of artifacts created by generators
   */
  public Precompilation(UnifiedAst unifiedAst,
      Collection<Permutation> permutations, int permutationBase,
      ArtifactSet generatedArtifacts) {

    this.unifiedAst = unifiedAst;
    this.permutations = new Permutation[permutations.size()];
    int i = 0;
    for (Permutation permutation : permutations) {
      this.permutations[i] = new Permutation(i + permutationBase, permutation);
      ++i;
    }
    this.generatedArtifacts = generatedArtifacts;
  }

  /**
   * Returns the set of generated artifacts from the precompile phase.
   */
  public ArtifactSet getGeneratedArtifacts() {
    if (generatedArtifacts == null) {
      try {
        assert generatedArtifactsSerialized != null;
        generatedArtifacts = Util.readStreamAsObject(new ByteArrayInputStream(
            generatedArtifactsSerialized), ArtifactSet.class);
        generatedArtifactsSerialized = null;
      } catch (ClassNotFoundException e) {
        throw new RuntimeException(
            "Unexpected exception deserializing from memory stream", e);
      } catch (IOException e) {
        throw new RuntimeException(
            "Unexpected exception deserializing from memory stream", e);
      }
    }
    return generatedArtifacts;
  }

  /**
   * Returns the set of permutations to run.
   */
  public Permutation[] getPermutations() {
    return permutations;
  }

  /**
   * Returns the unified AST used by
   * {@link com.google.gwt.dev.jjs.JavaToJavaScriptCompiler}.
   */
  public UnifiedAst getUnifiedAst() {
    return unifiedAst;
  }

  private void readObject(ObjectInputStream stream) throws IOException,
      ClassNotFoundException {
    stream.defaultReadObject();
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    Util.copyNoClose(stream, baos);
    generatedArtifactsSerialized = baos.toByteArray();
  }

  private void writeObject(ObjectOutputStream stream) throws IOException {
    stream.defaultWriteObject();
    Util.writeObjectToStream(stream, generatedArtifacts);
  }

  /**
   * Removes saved source code from the generated artifacts.
   * (This reduces I/O when we're not doing that.)
   */
  public void removeSourceArtifacts(TreeLogger logger) {
    logger.log(Type.DEBUG, "removing source artifacts");

    for (EmittedArtifact artifact : generatedArtifacts.find(EmittedArtifact.class)) {
      if (artifact.getVisibility() == Visibility.Source) {
        generatedArtifacts.remove(artifact);
      }
    }
  }
}
