/*
 * 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.NotFoundException;
import com.google.gwt.core.ext.typeinfo.TypeOracle;
import com.google.gwt.dev.javac.CompilationUnit;
import com.google.gwt.dev.javac.CompilationUnitInvalidator;
import com.google.gwt.dev.javac.JdtCompiler;
import com.google.gwt.dev.javac.TypeOracleMediator;

import java.io.FileNotFoundException;
import java.io.IOException;
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 units a set of CompilationUnits
   * @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<CompilationUnit> units,
      Set<String> excludedPackages, TreeLogger logger)
      throws UnableToCompleteException {
    this.name = name;
    this.logger = logger;
    logger.log(TreeLogger.INFO, "name = " + name + ", units.size = " + units.size(), null);
    try {
      this.typeOracle = getTypeOracleFromCompilationUnits(units);
    } catch (FileNotFoundException e2) {
      System.err.println("Do you have a reference version of the API checked out?");
      throw new IllegalArgumentException(e2);
    } catch (IOException e3) {
      throw new IllegalArgumentException(e3);
    } catch (NotFoundException e4) {
      logger.log(TreeLogger.ERROR, "logged a NotFoundException", e4);
      throw new UnableToCompleteException();
    }
    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 getTypeOracleFromCompilationUnits(
      Set<CompilationUnit> units) throws NotFoundException, IOException,
      UnableToCompleteException {
    JdtCompiler.compile(units);
    if (CompilationUnitInvalidator.invalidateUnitsWithErrors(logger, units)) {
      logger.log(TreeLogger.ERROR, "Unable to build typeOracle for "
          + getName());
      throw new UnableToCompleteException();
    }

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

}
