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

    TypeOracleMediator mediator = new TypeOracleMediator();
    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) {
    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);
  }

}
