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

import com.google.gwt.core.ext.typeinfo.JClassType;
import com.google.gwt.core.ext.typeinfo.JType;
import com.google.gwt.core.ext.typeinfo.NotFoundException;
import com.google.gwt.core.ext.typeinfo.TypeOracle;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

/**
 * {@link ApiDiffGenerator} encapsulates a class that produces the diff between
 * two api's.
 */
public final class ApiDiffGenerator {

  private static enum Relation {
    NONE, SUBCLASS, SUPERCLASS;
  }

  public static final String DELIMITER = " ";

  /* variable just for debugging -- find why an apiChange is being removed */
  static final String HAY_API_CHANGE = "";

  /**
   * The two types might belong to different typeOracles.
   */
  static boolean isFirstTypeAssignableToSecond(JType firstType, JType secondType) {

    // getJNISignature() does TypeErasure
    if (firstType.getJNISignature().equals(secondType.getJNISignature())) {
      return true;
    }
    JClassType classType1 = firstType.isClassOrInterface();
    JClassType classType2 = secondType.isClassOrInterface();
    if (classType1 == null || classType2 == null) {
      return false;
    }
    TypeOracle newApiTypeOracle = classType2.getOracle();
    // get the appropriate classObject in the newApi
    JClassType firstClassType = newApiTypeOracle.findType(classType1.getQualifiedSourceName());
    JClassType secondClassType = newApiTypeOracle.findType(classType2.getQualifiedSourceName());
    // The types might not necessarily exist in the newApi
    if (firstClassType == null || secondClassType == null) {
      return false;
    }
    return firstClassType.isAssignableTo(secondClassType);
  }

  static Set<String> removeIntersection(Set<String> s1, Set<String> s2) {
    Set<String> intersection = new HashSet<String>(s1);
    intersection.retainAll(s2);
    s1.removeAll(intersection);
    s2.removeAll(intersection);
    return intersection;
  }

  Map<String, ApiPackageDiffGenerator> intersectingPackages = new HashMap<String, ApiPackageDiffGenerator>();
  Set<String> missingPackageNames;

  final ApiContainer newApi;

  final ApiContainer oldApi;

  ApiDiffGenerator(ApiContainer newApi, ApiContainer oldApi) {
    this.newApi = newApi;
    this.oldApi = oldApi;
  }

  ApiClassDiffGenerator findApiClassDiffGenerator(String className) {
    int i = className.length() - 1;
    while (i >= 0) {
      int dot = className.lastIndexOf('.', i);
      String pkgName = "";
      String typeName = className;
      if (dot != -1) {
        pkgName = className.substring(0, dot);
        typeName = className.substring(dot + 1);
        i = dot - 1;
      } else {
        i = -1;
      }
      ApiClassDiffGenerator result = findApiClassDiffGenerator(pkgName,
          typeName);
      if (result != null) {
        return result;
      }
    }
    return null;
  }

  // TODO(amitmanjhi): cache the results
  /**
   * Finds a type given its package-relative name. For nested classes, use its
   * source name rather than its binary name (that is, use a "." rather than a
   * "$").
   * 
   * @return <code>null</code> if the type is not found
   */
  ApiClassDiffGenerator findApiClassDiffGenerator(String pkgName,
      String typeName) {
    ApiPackageDiffGenerator pkg = findApiPackageDiffGenerator(pkgName);
    if (pkg != null) {
      ApiClassDiffGenerator type = pkg.findApiClassDiffGenerator(pkgName + "."
          + typeName);
      if (type != null) {
        return type;
      }
    }
    return null;
  }

  ApiPackageDiffGenerator findApiPackageDiffGenerator(String key) {
    return intersectingPackages.get(key);
  }

  Collection<ApiChange> getApiDiff() throws NotFoundException {

    computeApiDiff();

    Collection<ApiChange> collection = new ArrayList<ApiChange>();
    Set<ApiPackage> missingPackages = oldApi.getApiPackagesBySet(missingPackageNames);
    for (ApiPackage missingPackage : missingPackages) {
      collection.add(new ApiChange(missingPackage, ApiChange.Status.MISSING));
    }
    for (ApiPackageDiffGenerator intersectingPackage : intersectingPackages.values()) {
      collection.addAll(intersectingPackage.getApiDiff());
    }
    return collection;
  }

  ApiContainer getNewApiContainer() {
    return newApi;
  }

  ApiContainer getOldApiContainer() {
    return oldApi;
  }

  /**
   * Remove any apiChange x if there is another apiChange y such that the
   * apiElement and status for both x and y are the same and the apiClass for x
   * is a subclass of the apiClass for y.
   * 
   * @param originalCollection collection with duplicates.
   * @return collection minus duplicates.
   */
  Collection<ApiChange> removeDuplicates(
      Collection<ApiChange> originalCollection) {
    /*
     * Map from the hashCode of an apiChange to the list of ApiChanges. There
     * can be multiple ApiChanges that have the same hashCode, but neither is a
     * subset of another. Example: if B and C both extend A, and there is an
     * ApiChange in B and C due to an api element of A.
     */
    Map<Integer, Collection<ApiChange>> apiChangeMap = new HashMap<Integer, Collection<ApiChange>>();
    for (ApiChange apiChange : originalCollection) {
      String apiChangeStr = apiChange.getApiElement().getRelativeSignature();
      Collection<ApiChange> apiChangesSameHashCode = apiChangeMap.get(apiChange.hashCodeForDuplication());
      if (apiChangesSameHashCode == null) {
        apiChangesSameHashCode = new HashSet<ApiChange>();
        apiChangeMap.put(apiChange.hashCodeForDuplication(),
            apiChangesSameHashCode);
      }
      Collection<ApiChange> apiChangesToRemove = new HashSet<ApiChange>();
      boolean addNewElement = true;

      for (ApiChange oldApiChange : apiChangesSameHashCode) {
        String oldApiChangeStr = oldApiChange.getApiElement().getRelativeSignature();
        Relation relation = getRelationOfApiClassOfFirstArgToThatOfSecond(
            apiChange.getApiElement(), oldApiChange.getApiElement());
        if (relation == Relation.SUPERCLASS) {
          apiChangesToRemove.add(oldApiChange);
          if (ApiCompatibilityChecker.DEBUG_DUPLICATE_REMOVAL
              && oldApiChangeStr.indexOf(HAY_API_CHANGE) != -1) {
            System.out.println(oldApiChangeStr + " replaced by " + apiChangeStr
                + ", status = " + oldApiChange.getStatus());
          }
        } else if (relation == Relation.SUBCLASS) {
          addNewElement = false;
          if (ApiCompatibilityChecker.DEBUG_DUPLICATE_REMOVAL
              && apiChangeStr.indexOf(HAY_API_CHANGE) != -1) {
            System.out.println(apiChangeStr + " replaced by " + oldApiChangeStr);
          }
        }
      }
      apiChangesSameHashCode.removeAll(apiChangesToRemove);
      if (addNewElement) {
        apiChangesSameHashCode.add(apiChange);
      }
    }
    Collection<ApiChange> prunedCollection = new HashSet<ApiChange>();
    for (Collection<ApiChange> changes : apiChangeMap.values()) {
      prunedCollection.addAll(changes);
    }
    return prunedCollection;
  }

  /**
   * Compares 2 APIs for source compatibility. Algorithm: First find packages
   * that are in one but not in another. Then, look at at classes in the common
   * packages. Look at public classes.
   * 
   */
  private void computeApiDiff() throws NotFoundException {
    Set<String> newApiPackageNames = newApi.getApiPackageNames();
    missingPackageNames = oldApi.getApiPackageNames();
    Set<String> intersection = removeIntersection(newApiPackageNames,
        missingPackageNames);
    // Inspect each of the classes in each of the packages in the intersection
    for (String packageName : intersection) {
      ApiPackageDiffGenerator tempPackageDiffGenerator = new ApiPackageDiffGenerator(
          packageName, this);
      intersectingPackages.put(packageName, tempPackageDiffGenerator);
      tempPackageDiffGenerator.computeApiDiff();
    }
  }

  /**
   * Returns how ApiClass for first element is "related" to the ApiClass for
   * secondElement.
   */
  private Relation getRelationOfApiClassOfFirstArgToThatOfSecond(
      ApiElement firstApiElement, ApiElement secondApiElement) {
    JClassType firstClassType = null;
    JClassType secondClassType = null;
    if (firstApiElement instanceof ApiField) {
      firstClassType = ((ApiField) firstApiElement).getApiClass().getClassObject();
      secondClassType = ((ApiField) secondApiElement).getApiClass().getClassObject();
    }
    if (firstApiElement instanceof ApiAbstractMethod) {
      firstClassType = ((ApiAbstractMethod) firstApiElement).getApiClass().getClassObject();
      secondClassType = ((ApiAbstractMethod) secondApiElement).getApiClass().getClassObject();
    }
    if (firstClassType != null && secondClassType != null) {
      if (secondClassType.isAssignableTo(firstClassType)) {
        return Relation.SUPERCLASS;
      }
      if (firstClassType.isAssignableTo(secondClassType)) {
        return Relation.SUBCLASS;
      }
      return Relation.NONE;
    }
    throw new RuntimeException(
        "Inconsistent types for ApiElements: newApiElement " + firstApiElement
            + ", oldApiElement : " + secondApiElement);
  }

}
