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

import com.google.gwt.dev.jjs.impl.GwtAstBuilder;
import com.google.gwt.dev.util.DiskCacheToken;
import com.google.gwt.dev.util.Util;

import org.eclipse.jdt.core.compiler.CategorizedProblem;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

/**
 * A convenient way to serialize a {@CompilationUnit}.
 */
public class CachedCompilationUnit extends CompilationUnit {
  private static final boolean normalizeTimestamps = Boolean.parseBoolean(
      System.getProperty("gwt.normalizeTimestamps", "false"));

  private final DiskCacheToken astToken;
  private final long astVersion;
  private transient Collection<CompiledClass> compiledClasses;
  private final ContentId contentId;
  private final Dependencies dependencies;
  private final boolean isError;
  private final boolean isGenerated;
  private final boolean isSuperSource;
  private final boolean hasJsInteropRootType;
  private transient List<JsniMethod> jsniMethods;
  private final long lastModified;
  private final MethodArgNamesLookup methodArgNamesLookup;
  private final CategorizedProblem[] problems;
  private final String resourceLocation;
  private final String resourcePath;
  private final String typeName;

  /**
   * Shallow copy of a CachedCompiliationUnit, replacing some parameters in the new copy.
   *
   * @param unit Unit to clone.
   * @param lastModified last modified date to replace in the clone
   * @param resourceLocation location to replace in the clone.
   */
  public CachedCompilationUnit(CachedCompilationUnit unit, long lastModified,
      String resourceLocation) {
    assert unit != null;
    this.compiledClasses = CompiledClass.copyForUnit(unit.getCompiledClasses(), this);
    this.hasJsInteropRootType = unit.hasJsInteropRootType;
    this.contentId = unit.getContentId();
    this.dependencies = unit.getDependencies();
    this.resourcePath = unit.getResourcePath();
    this.resourceLocation = Util.stripJarPathPrefix(resourceLocation);
    this.jsniMethods = unit.getJsniMethods();
    this.methodArgNamesLookup = unit.getMethodArgs();
    this.typeName = unit.getTypeName();
    this.isError = unit.isError();
    this.isGenerated = unit.isGenerated();
    this.isSuperSource = unit.isSuperSource();
    this.problems = unit.problems;
    this.astToken = unit.astToken;
    this.astVersion = unit.astVersion;

    // Override these fields
    this.lastModified = normalizeTimestamps ? 0 : lastModified;
  }

  /**
   * Create a compilation unit that can be serialized from another
   * {@link CompilationUnit}.
   *
   * @param unit A unit to copy
   * @param astToken A valid {@DiskCache} token for this unit's
   *          serialized AST types.
   */
  @SuppressWarnings("deprecation")
  CachedCompilationUnit(CompilationUnit unit, long astToken) {
    assert unit != null;
    this.compiledClasses = CompiledClass.copyForUnit(unit.getCompiledClasses(), this);
    this.hasJsInteropRootType = unit.hasJsInteropRootType();
    this.contentId = unit.getContentId();
    this.dependencies = unit.getDependencies();
    this.resourcePath = unit.getResourcePath();
    this.resourceLocation = Util.stripJarPathPrefix(unit.getResourceLocation());
    this.jsniMethods = unit.getJsniMethods();
    this.lastModified = normalizeTimestamps ? 0 : unit.getLastModified();
    this.methodArgNamesLookup = unit.getMethodArgs();
    this.typeName = unit.getTypeName();
    this.isError = unit.isError();
    this.isGenerated = unit.isGenerated();
    this.isSuperSource = unit.isSuperSource();
    CategorizedProblem[] problemsIn = unit.getProblems();
    if (problemsIn == null) {
      this.problems = null;
    } else {
      this.problems = new CategorizedProblem[problemsIn.length];
      for (int i = 0; i < problemsIn.length; i++) {
        this.problems[i] = new SerializableCategorizedProblem(problemsIn[i]);
      }
    }
    this.astToken = new DiskCacheToken(astToken);
    this.astVersion = GwtAstBuilder.getSerializationVersion();
  }

  @Override
  public CachedCompilationUnit asCachedCompilationUnit() {
    return this;
  }

  @Override
  public Collection<CompiledClass> getCompiledClasses() {
    return compiledClasses;
  }

  @Override
  public List<JsniMethod> getJsniMethods() {
    return jsniMethods;
  }

  @Override
  public long getLastModified() {
    return lastModified;
  }

  @Override
  public MethodArgNamesLookup getMethodArgs() {
    return methodArgNamesLookup;
  }

  @Override
  public String getResourceLocation() {
    return resourceLocation;
  }

  @Override
  public String getResourcePath() {
    return resourcePath;
  }

  @Override
  public String getTypeName() {
    return typeName;
  }

  @Override
  public byte[] getTypesSerialized() {
    return astToken.readByteArray();
  }

  @Override
  public boolean isError() {
    return isError;
  }

  @Override
  @Deprecated
  public boolean isGenerated() {
    return isGenerated;
  }

  @Override
  @Deprecated
  public boolean isSuperSource() {
    return isSuperSource;
  }

  @Override
  boolean hasJsInteropRootType() {
    return hasJsInteropRootType;
  }

  @Override
  ContentId getContentId() {
    return contentId;
  }

  @Override
  Dependencies getDependencies() {
    return dependencies;
  }

  @Override
  CategorizedProblem[] getProblems() {
    return problems;
  }

  long getTypesSerializedVersion() {
    return astVersion;
  }

  @SuppressWarnings("unchecked")
  private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {
    ois.defaultReadObject();
    this.compiledClasses = (Collection<CompiledClass>) ois.readObject();
    this.jsniMethods = (List<JsniMethod>) ois.readObject();
  }

  private <T> Collection<T> sort(Collection<T> collection, Comparator<T> comparator) {
    if (collection == null) {
      return null;
    }

    // copy because the source may be unmodifiable or singleton
    ArrayList<T> copy = new ArrayList<T>(collection);

    Collections.sort(copy, comparator);
    return copy;
  }

  private void writeObject(ObjectOutputStream oos) throws IOException {
    oos.defaultWriteObject();
    oos.writeObject(sort(this.compiledClasses, new Comparator<CompiledClass>() {
      @Override
      public int compare(CompiledClass o1, CompiledClass o2) {
        return o1.getSourceName().compareTo(o2.getSourceName());
      }
    }));
    oos.writeObject(sort(this.jsniMethods, new Comparator<JsniMethod>() {
      @Override
      public int compare(JsniMethod o1, JsniMethod o2) {
         return o1.name().compareTo(o2.name());
      }
    }));
  }
}
