/*
 * 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.linker.ArtifactSet;
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.io.Serializable;
import java.util.Collection;

/**
 * The result of compilation phase 1, includes a unified AST and metadata
 * relevant to each permutation.
 */
public class Precompilation implements Serializable, 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;

  public Precompilation(UnifiedAst unifiedAst,
      Collection<Permutation> permutations, ArtifactSet generatedArtifacts) {
    this(unifiedAst, permutations, 0, generatedArtifacts);
  }

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

  public Permutation getPermutation(int id) {
    for (Permutation perm : permutations) {
      if (perm.getId() == id) {
        return perm;
      }
    }
    return null;
  }

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