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

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