/*
 * 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.TreeLogger;
import com.google.gwt.core.ext.UnableToCompleteException;
import com.google.gwt.core.ext.typeinfo.JClassType;
import com.google.gwt.core.ext.typeinfo.JConstructor;
import com.google.gwt.core.ext.typeinfo.JPackage;
import com.google.gwt.core.ext.typeinfo.TypeOracle;
import com.google.gwt.dev.javac.CompilationUnit;
import com.google.gwt.dev.javac.CompilationUnitBuilder;
import com.google.gwt.dev.javac.CompilationUnitInvalidator;
import com.google.gwt.dev.javac.JdtCompiler;
import com.google.gwt.dev.javac.TypeOracleMediatorFromSource;
import com.google.gwt.dev.resource.Resource;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * {@link ApiContainer} Encapsulates an API.
 * 
 */
public final class ApiContainer {

  private final Map<JClassType, Boolean> apiClassCache = new HashMap<JClassType, Boolean>();
  private final Map<String, ApiPackage> apiPackages = new HashMap<String, ApiPackage>();

  private final Set<String> excludedPackages;
  private final TreeLogger logger;
  private final String name;

  private final TypeOracle typeOracle;

  /**
   * A public constructor used for programmatic invocation and testing.
   * 
   * @param name Api name
   * @param resources a set of Resources
   * @param excludedPackages a set of excludedPackages
   * @param logger TreeLogger for logging messages
   * @throws IllegalArgumentException if one of the arguments is illegal
   * @throws UnableToCompleteException if there is a TypeOracle exception
   */
  ApiContainer(String name, Set<Resource> resources,
      Set<String> excludedPackages, TreeLogger logger)
      throws UnableToCompleteException {
    this.name = name;
    this.logger = logger;
    logger.log(TreeLogger.INFO, "name = " + name + ", builders.size = "
        + resources.size(), null);
    this.typeOracle = createTypeOracle(resources);
    this.excludedPackages = excludedPackages;
    initializeApiPackages();
  }

  /**
   * Get all the API members as String.
   * 
   * @return the string value
   */
  public String getApiAsString() {
    StringBuffer sb = new StringBuffer();
    sb.append("Api: " + name + ", size = " + apiPackages.size() + "\n\n");
    List<ApiPackage> sortedApiPackages = new ArrayList<ApiPackage>(
        apiPackages.values());
    Collections.sort(sortedApiPackages);
    for (ApiPackage apiPackage : sortedApiPackages) {
      sb.append(apiPackage.getApiAsString());
    }
    return sb.toString();
  }

  ApiPackage getApiPackage(String packageName) {
    return apiPackages.get(packageName);
  }

  HashSet<String> getApiPackageNames() {
    return new HashSet<String>(apiPackages.keySet());
  }

  Set<ApiPackage> getApiPackagesBySet(Set<String> names) {
    Set<ApiPackage> ret = new HashSet<ApiPackage>();
    for (String packageName : names) {
      ret.add(apiPackages.get(packageName));
    }
    return ret;
  }

  TreeLogger getLogger() {
    return logger;
  }

  String getName() {
    return name;
  }

  boolean isApiClass(JClassType classType) {
    Boolean ret = apiClassCache.get(classType);
    if (ret != null) {
      return ret.booleanValue();
    }
    // to avoid infinite recursion for isApiClass("BAR", ..) when:
    // class FOO {
    // public class BAR extends FOO {
    // }
    // }
    apiClassCache.put(classType, Boolean.FALSE);
    boolean bool = computeIsApiClass(classType);
    if (bool) {
      apiClassCache.put(classType, Boolean.TRUE);
    } else {
      apiClassCache.put(classType, Boolean.FALSE);
    }
    // container.getLogger().log(TreeLogger.SPAM, "computed isApiClass for " +
    // classType + " as " + bool, null);
    return bool;
  }

  boolean isInstantiableApiClass(JClassType classType) {
    return !classType.isAbstract() && isApiClass(classType)
        && hasPublicOrProtectedConstructor(classType);
  }

  boolean isNotsubclassableApiClass(JClassType classType) {
    return isApiClass(classType) && !isSubclassable(classType);
  }

  boolean isSubclassableApiClass(JClassType classType) {
    return isApiClass(classType) && isSubclassable(classType);
  }

  /**
   * Assumption: Clients may subclass an API class, but they will not add their
   * class to the package.
   * 
   * Notes: -- A class with only private constructors can be an API class.
   */
  private boolean computeIsApiClass(JClassType classType) {
    if (excludedPackages.contains(classType.getPackage().getName())) {
      return false;
    }

    // check for outer classes
    if (isPublicOuterClass(classType)) {
      return true;
    }
    // if classType is not a member type, return false
    if (!classType.isMemberType()) {
      return false;
    }
    JClassType enclosingType = classType.getEnclosingType();
    if (classType.isPublic()) {
      return isApiClass(enclosingType) || isAnySubtypeAnApiClass(enclosingType);
    }
    if (classType.isProtected()) {
      return isSubclassableApiClass(enclosingType)
          || isAnySubtypeASubclassableApiClass(enclosingType);
    }
    return false;
  }

  private TypeOracle createTypeOracle(Set<Resource> resources)
      throws UnableToCompleteException {
    List<CompilationUnitBuilder> builders = new ArrayList<CompilationUnitBuilder>();
    for (Resource resource : resources) {
      CompilationUnitBuilder builder = CompilationUnitBuilder.create(resource);
      builders.add(builder);
    }
    List<CompilationUnit> units = JdtCompiler.compile(builders);
    boolean anyError = false;
    TreeLogger branch = logger.branch(TreeLogger.TRACE,
        "Checking for compile errors");
    for (CompilationUnit unit : units) {
      CompilationUnitInvalidator.reportErrors(branch, unit);
      anyError |= unit.isError();
    }
    if (anyError) {
      logger.log(TreeLogger.ERROR, "Unable to build typeOracle for "
          + getName());
      throw new UnableToCompleteException();
    }

    TypeOracleMediatorFromSource mediator = new TypeOracleMediatorFromSource();
    mediator.addNewUnits(logger, units);
    logger.log(TreeLogger.INFO, "API " + name
        + ", Finished with building typeOracle, added " + units.size()
        + " files", null);
    return mediator.getTypeOracle();
  }

  private boolean hasPublicOrProtectedConstructor(JClassType classType) {
    JConstructor[] constructors = classType.getConstructors();
    for (JConstructor constructor : constructors) {
      if (constructor.isPublic() || constructor.isProtected()) {
        return true;
      }
    }
    return false;
  }

  /**
   * Purge non API packages.
   */
  private void initializeApiPackages() {
    Set<JPackage> allPackages = new HashSet<JPackage>(
        Arrays.asList(typeOracle.getPackages()));
    Set<String> packagesNotAdded = new HashSet<String>();
    for (JPackage packageObject : allPackages) {
      if (isApiPackage(packageObject)) {
        ApiPackage apiPackageObj = new ApiPackage(packageObject, this);
        apiPackages.put(apiPackageObj.getName(), apiPackageObj);
      } else {
        packagesNotAdded.add(packageObject.toString());
      }
    }
    if (packagesNotAdded.size() > 0) {
      logger.log(TreeLogger.DEBUG, "API " + name + ": not added "
          + packagesNotAdded.size() + " packages: " + packagesNotAdded, null);
    }
    if (apiPackages.size() > 0) {
      logger.log(TreeLogger.INFO, "API " + name + " " + apiPackages.size()
          + " Api packages: " + apiPackages.keySet(), null);
    }
  }

  private boolean isAnySubtypeAnApiClass(JClassType classType) {
    JClassType subTypes[] = classType.getSubtypes();
    for (JClassType tempType : subTypes) {
      if (isApiClass(tempType)) {
        return true;
      }
    }
    return false;
  }

  private boolean isAnySubtypeASubclassableApiClass(JClassType classType) {
    JClassType subTypes[] = classType.getSubtypes();
    for (JClassType tempType : subTypes) {
      if (isSubclassableApiClass(tempType)) {
        return true;
      }
    }
    return false;
  }

  /**
   * A package is an API package if it contains at least one API class. Refer
   * http://wiki.eclipse.org/index.php/Evolving_Java-based_APIs This definition
   * boils down to "a package is an API package iff it contains at least one API
   * class that is not enclosed in any other class."
   * 
   * @return return true if and only if the packageObject is an apiPackage
   */
  private boolean isApiPackage(JPackage packageObject) {
    if (excludedPackages.contains(packageObject.getName())) {
      return false;
    }
    JClassType classTypes[] = packageObject.getTypes();
    for (JClassType classType : classTypes) {
      if (isPublicOuterClass(classType)) {
        return true;
      }
    }
    return false;
  }

  /**
   * @return returns true if classType is public AND an outer class
   */
  private boolean isPublicOuterClass(JClassType classType) {
    return classType.isPublic() && !classType.isMemberType();
  }

  private boolean isSubclassable(JClassType classType) {
    return !classType.isFinal() && hasPublicOrProtectedConstructor(classType);
  }

}
