/*
 * 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.dev.cfg;

import com.google.gwt.core.ext.Linker;
import com.google.gwt.core.ext.TreeLogger;
import com.google.gwt.core.ext.UnableToCompleteException;
import com.google.gwt.core.ext.linker.LinkerOrder;
import com.google.gwt.core.ext.linker.LinkerOrder.Order;
import com.google.gwt.core.ext.typeinfo.TypeOracle;
import com.google.gwt.dev.CompilerContext;
import com.google.gwt.dev.javac.CompilationProblemReporter;
import com.google.gwt.dev.javac.CompilationState;
import com.google.gwt.dev.javac.CompilationStateBuilder;
import com.google.gwt.dev.resource.Resource;
import com.google.gwt.dev.resource.ResourceOracle;
import com.google.gwt.dev.resource.impl.DefaultFilters;
import com.google.gwt.dev.resource.impl.PathPrefix;
import com.google.gwt.dev.resource.impl.PathPrefixSet;
import com.google.gwt.dev.resource.impl.ResourceFilter;
import com.google.gwt.dev.resource.impl.ResourceOracleImpl;
import com.google.gwt.dev.util.Empty;
import com.google.gwt.dev.util.Util;
import com.google.gwt.dev.util.log.speedtracer.CompilerEventType;
import com.google.gwt.dev.util.log.speedtracer.SpeedTracerLogger;
import com.google.gwt.dev.util.log.speedtracer.SpeedTracerLogger.Event;
import com.google.gwt.thirdparty.guava.common.base.Charsets;
import com.google.gwt.thirdparty.guava.common.base.Predicates;
import com.google.gwt.thirdparty.guava.common.collect.ImmutableList;
import com.google.gwt.thirdparty.guava.common.collect.Iterators;
import com.google.gwt.thirdparty.guava.common.collect.Lists;
import com.google.gwt.thirdparty.guava.common.collect.Maps;
import com.google.gwt.thirdparty.guava.common.collect.Sets;

import java.io.File;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.Deque;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

/**
 * Represents a module specification. In principle, this could be built without
 * XML for unit tests.
 */
public class ModuleDef implements DepsInfoProvider {
  private static final ResourceFilter NON_JAVA_RESOURCES = new ResourceFilter() {
    @Override
    public boolean allows(String path) {
      return !path.endsWith(".java") && !path.endsWith(".class");
    }
  };

  private static final Comparator<Map.Entry<String, ?>> REV_NAME_CMP =
      new Comparator<Map.Entry<String, ?>>() {
        @Override
        public int compare(Map.Entry<String, ?> entry1, Map.Entry<String, ?> entry2) {
          String key1 = entry1.getKey();
          String key2 = entry2.getKey();
          // intentionally reversed
          return key2.compareTo(key1);
        }
      };

  public static boolean isValidModuleName(String moduleName) {
    // Check for an empty string between two periods.
    if (moduleName.contains("..")) {
      return false;
    }
    // Insure the package name components are a valid Java ident.
    String[] parts = moduleName.split("\\.");
    for (int i = 0; i < parts.length - 1; i++) {
      String part = parts[i];
      if (!Util.isValidJavaIdent(part)) {
        return false;
      }
    }
    return true;
  }

  /**
   * All resources found on the public path, specified by <public> directives in
   * modules (or the implicit ./public directory). Marked 'lazy' because it does not
   * start searching for resources until a query is made.
   */
  protected ResourceOracleImpl lazyPublicOracle;

  private final Set<String> activeLinkers = new LinkedHashSet<String>();

  private String activePrimaryLinker;

  private boolean collapseAllProperties;

  private final DefaultFilters defaultFilters;

  private final List<String> entryPointTypeNames = new ArrayList<String>();

  /**
   * A stack that keeps track of the name of the current module in the enterModule/exitModule tree.
   */
  private final Deque<String> currentLibraryModuleNames = Lists.newLinkedList();

  private final Set<File> gwtXmlFiles = new HashSet<File>();

  private final Set<String> inheritedModules = new HashSet<String>();

  /**
   * Contains files other than .java and .class files (such as CSS and PNG files) from either the
   * source or resource paths.
   */
  private ResourceOracleImpl lazyResourcesOracle;

  /**
   * Contains all files from the source path, specified by <source> and <super>
   * directives in modules (or the implicit ./client directory).
   */
  private ResourceOracleImpl lazySourceOracle;

  private final Map<String, Class<? extends Linker>> linkerTypesByName =
      new LinkedHashMap<String, Class<? extends Linker>>();

  private final long moduleDefCreationTime = System.currentTimeMillis();

  private final String name;

  /**
   * Must use a separate field to track override, because setNameOverride() will
   * get called every time a module is inherited, but only the last one matters.
   */
  private String nameOverride;

  private final Properties properties = new Properties();

  private PathPrefixSet publicPrefixSet = new PathPrefixSet();

  private Set<PathPrefix> resourcePrefixes = Sets.newHashSet();

  private final ResourceLoader resources;

  private boolean resourcesScanned;

  private final Deque<Rule> rules = Lists.newLinkedList();

  private final Scripts scripts = new Scripts();

  private final Map<String, String> servletClassNamesByPath = new HashMap<String, String>();

  private final PathPrefixSet sourcePrefixSet;

  private final Styles styles = new Styles();

  /**
   * A mapping from names of modules to path to their associated .gwt.xml file.
   */
  private Map<String, String> gwtXmlPathByModuleName = Maps.newHashMap();

  public ModuleDef(String name) {
    this(name, ResourceLoaders.fromContextClassLoader());
  }

  public ModuleDef(String name, ResourceLoader resources) {
    this(name, resources, true, true);
  }

  /**
   * Constructs a ModuleDef.
   */
  public ModuleDef(String name, ResourceLoader resources, boolean monolithic,
      boolean mergePathPrefixes) {
    this.name = name;
    this.resources = resources;
    sourcePrefixSet = new PathPrefixSet(mergePathPrefixes);
    defaultFilters = new DefaultFilters();
  }

  public synchronized void addEntryPointTypeName(String typeName) {
    entryPointTypeNames.add(typeName);
  }

  public void addGwtXmlFile(File xmlFile) {
    gwtXmlFiles.add(xmlFile);
  }

  public void addLinker(String name) {
    Class<? extends Linker> clazz = getLinker(name);
    assert clazz != null;

    LinkerOrder order = clazz.getAnnotation(LinkerOrder.class);
    if (order.value() == Order.PRIMARY) {
      if (activePrimaryLinker != null) {
        activeLinkers.remove(activePrimaryLinker);
      }
      activePrimaryLinker = name;
    }

    activeLinkers.add(name);
  }

  public synchronized void addPublicPackage(String publicPackage, String[] includeList,
      String[] excludeList, String[] skipList, boolean defaultExcludes, boolean caseSensitive) {
    if (lazyPublicOracle != null) {
      throw new IllegalStateException("Already normalized");
    }
    publicPrefixSet.add(new PathPrefix(getCurrentLibraryModuleName(), publicPackage, defaultFilters
        .customResourceFilter(includeList, excludeList, skipList, defaultExcludes, caseSensitive),
        true, excludeList));
  }

  public void addResourcePath(String resourcePath) {
    if (lazyResourcesOracle != null) {
      throw new IllegalStateException("Already normalized");
    }
    resourcePrefixes.add(new PathPrefix(getCurrentLibraryModuleName(), resourcePath,
        NON_JAVA_RESOURCES, false, null));
  }

  public void addRule(Rule rule) {
    getRules().addFirst(rule);
  }

  public void addSourcePackage(String sourcePackage, String[] includeList, String[] excludeList,
      String[] skipList, boolean defaultExcludes, boolean caseSensitive) {
    addSourcePackageImpl(sourcePackage, includeList, excludeList, skipList, defaultExcludes,
        caseSensitive, false);
  }

  public void addSourcePackageImpl(String sourcePackage, String[] includeList,
      String[] excludeList, String[] skipList, boolean defaultExcludes, boolean caseSensitive,
      boolean isSuperSource) {
    if (lazySourceOracle != null) {
      throw new IllegalStateException("Already normalized");
    }
    PathPrefix pathPrefix = new PathPrefix(getCurrentLibraryModuleName(),
        sourcePackage, defaultFilters.customJavaFilter(includeList, excludeList, skipList,
            defaultExcludes, caseSensitive), isSuperSource, excludeList);
    sourcePrefixSet.add(pathPrefix);
  }

  public void addSuperSourcePackage(String superSourcePackage, String[] includeList,
      String[] excludeList, String[] skipList, boolean defaultExcludes, boolean caseSensitive) {
    addSourcePackageImpl(superSourcePackage, includeList, excludeList, skipList, defaultExcludes,
        caseSensitive, true);
  }

  public void clearEntryPoints() {
    entryPointTypeNames.clear();
  }

  /**
   * Deactivate a linker by name. Returns false if the linker was not active, true otherwise.
   */
  public boolean deactivateLinker(String linkerName) {
    return activeLinkers.remove(linkerName);
  }

  /**
   * Associate a Linker class with a symbolic name. If the name had been
   * previously assigned, this method will redefine the name. If the redefined
   * linker had been previously added to the set of active linkers, the old
   * active linker will be replaced with the new linker.
   */
  public void defineLinker(TreeLogger logger, String name, Class<? extends Linker> linker)
      throws UnableToCompleteException {
    Class<? extends Linker> old = getLinker(name);
    if (old != null) {
      // Redefining an existing name
      if (activePrimaryLinker.equals(name)) {
        // Make sure the new one is also a primary linker
        if (!linker.getAnnotation(LinkerOrder.class).value().equals(Order.PRIMARY)) {
          logger.log(TreeLogger.ERROR, "Redefining primary linker " + name
              + " with non-primary implementation " + linker.getName());
          throw new UnableToCompleteException();
        }

      } else if (activeLinkers.contains(name)) {
        // Make sure it's a not a primary linker
        if (linker.getAnnotation(LinkerOrder.class).value().equals(Order.PRIMARY)) {
          logger.log(TreeLogger.ERROR, "Redefining non-primary linker " + name
              + " with primary implementation " + linker.getName());
          throw new UnableToCompleteException();
        }
      }
    }
    linkerTypesByName.put(name, linker);
  }

  /**
   * Called as module tree parsing enters and exits individual module file of various types and so
   * provides the ModuleDef with an opportunity to keep track of what context it is currently
   * operating.
   */
  public void enterModule(String canonicalModuleName) {
    currentLibraryModuleNames.push(canonicalModuleName);
  }

  public void exitModule() {
    currentLibraryModuleNames.pop();
  }

  public synchronized Resource findPublicFile(String partialPath) {
    ensureResourcesScanned();
    return lazyPublicOracle.getResource(partialPath);
  }

  public synchronized String findServletForPath(String actual) {
    // Walk in backwards sorted order to find the longest path match first.
    Set<Entry<String, String>> entrySet = servletClassNamesByPath.entrySet();
    Entry<String, String>[] entries = Util.toArray(Entry.class, entrySet);
    Arrays.sort(entries, REV_NAME_CMP);
    for (int i = 0, n = entries.length; i < n; ++i) {
      String mapping = entries[i].getKey();
      /*
       * Ensure that URLs that match the servlet mapping, including those that
       * have additional path_info, get routed to the correct servlet.
       *
       * See "Inside Servlets", Second Edition, pg. 208
       */
      if (actual.equals(mapping) || actual.startsWith(mapping + "/")) {
        return entries[i].getValue();
      }
    }
    return null;
  }

  /**
   * Returns the Resource for a source file if it is found; <code>null</code>
   * otherwise.
   *
   * @param partialPath the partial path of the source file
   * @return the resource for the requested source file
   */
  public synchronized Resource findSourceFile(String partialPath) {
    ensureResourcesScanned();
    return lazySourceOracle.getResource(partialPath);
  }

  public Set<String> getActiveLinkerNames() {
    return new LinkedHashSet<String>(activeLinkers);
  }

  public Set<Class<? extends Linker>> getActiveLinkers() {
    Set<Class<? extends Linker>> toReturn = new LinkedHashSet<Class<? extends Linker>>();
    for (String linker : activeLinkers) {
      assert linkerTypesByName.containsKey(linker) : linker;
      toReturn.add(linkerTypesByName.get(linker));
    }
    return toReturn;
  }

  public Class<? extends Linker> getActivePrimaryLinker() {
    assert linkerTypesByName.containsKey(activePrimaryLinker) : activePrimaryLinker;
    return linkerTypesByName.get(activePrimaryLinker);
  }

  /**
   * Strictly for statistics gathering. There is no guarantee that the source
   * oracle has been initialized.
   */
  public String[] getAllSourceFiles() {
    ensureResourcesScanned();
    return lazySourceOracle.getPathNames().toArray(Empty.STRINGS);
  }

  public synchronized ResourceOracle getBuildResourceOracle() {
    if (lazyResourcesOracle == null) {
      lazyResourcesOracle = new ResourceOracleImpl(TreeLogger.NULL, resources);
      PathPrefixSet pathPrefixes = lazySourceOracle.getPathPrefixes();

      // For backwards compatibility, register source resource paths as build resource paths as
      // well.
      PathPrefixSet newPathPrefixes = new PathPrefixSet();
      for (PathPrefix pathPrefix : pathPrefixes.values()) {
        newPathPrefixes.add(new PathPrefix(pathPrefix.getModuleName(), pathPrefix.getPrefix(),
            NON_JAVA_RESOURCES, pathPrefix.shouldReroot(), null));
      }

      // Register build resource paths.
      for (PathPrefix resourcePathPrefix : resourcePrefixes) {
        newPathPrefixes.add(resourcePathPrefix);
      }
      lazyResourcesOracle.setPathPrefixes(newPathPrefixes);
      lazyResourcesOracle.scanResources(TreeLogger.NULL);
    } else {
      ensureResourcesScanned();
    }
    return lazyResourcesOracle;
  }

  /**
   * Returns the physical name for the module by which it can be found in the
   * classpath.
   */
  public String getCanonicalName() {
    return name;
  }

  public CompilationState getCompilationState(TreeLogger logger, CompilerContext compilerContext)
      throws UnableToCompleteException {
    ensureResourcesScanned();
    CompilationState compilationState = CompilationStateBuilder.buildFrom(
        logger, compilerContext, compilerContext.getSourceResourceOracle().getResources());
    checkForSeedTypes(logger, compilationState);
    return compilationState;
  }

  public synchronized String[] getEntryPointTypeNames() {
    final int n = entryPointTypeNames.size();
    return entryPointTypeNames.toArray(new String[n]);
  }

  public synchronized String getFunctionName() {
    return getName().replace('.', '_');
  }

  public List<Rule> getGeneratorRules() {
    return ImmutableList.copyOf(
        Iterators.filter(rules.iterator(), Predicates.instanceOf(RuleGenerateWith.class)));
  }

  @Override
  public String getGwtXmlFilePath(String moduleName) {
    return gwtXmlPathByModuleName.get(moduleName);
  }

  /**
   * Calculates a hash of the filenames of all the input files for the GWT compiler.
   *
   * <p> This is needed because the list of files could change without affecting the timestamp.
   * For example, consider a glob that matches fewer files than before because a file was
   * deleted.
   */
  public int getInputFilenameHash() {
    List<String> filenames = new ArrayList<String>();

    filenames.addAll(gwtXmlPathByModuleName.values());

    for (Resource resource : getResourcesNewerThan(Integer.MIN_VALUE)) {
      filenames.add(resource.getLocation());
    }

    // Take the first four bytes of the SHA-1 hash.

    Collections.sort(filenames);

    MessageDigest digest;
    try {
      digest = MessageDigest.getInstance("SHA-1");
    } catch (NoSuchAlgorithmException e) {
      throw new RuntimeException("SHA-1 unavailable", e);
    }
    for (String filename : filenames) {
      digest.update(filename.getBytes(Charsets.UTF_8));
    }
    byte[] bytes = digest.digest();

    return (bytes[0] << 24) | (bytes[1] << 16) | (bytes[2] << 8) | bytes[3];
  }

  public Class<? extends Linker> getLinker(String name) {
    return linkerTypesByName.get(name);
  }

  public Map<String, Class<? extends Linker>> getLinkers() {
    return linkerTypesByName;
  }

  public synchronized String getName() {
    return nameOverride != null ? nameOverride : name;
  }

  /**
   * The properties that have been defined.
   */
  public synchronized Properties getProperties() {
    return properties;
  }

  public ResourceOracleImpl getPublicResourceOracle() {
    ensureResourcesScanned();
    return lazyPublicOracle;
  }

  public long getResourceLastModified() {
    long resourceLastModified = 1000;
    Set<Resource> allResources = Sets.newHashSet();
    allResources.addAll(getPublicResourceOracle().getResources());
    allResources.addAll(getSourceResourceOracle().getResources());
    allResources.addAll(getBuildResourceOracle().getResources());
    for (Resource resource : allResources) {
      resourceLastModified = Math.max(resourceLastModified, resource.getLastModified());
    }
    return resourceLastModified;
  }

  public Set<Resource> getResourcesNewerThan(long modificationTime) {
    Set<Resource> newerResources = Sets.newHashSet();

    for (Resource resource : getPublicResourceOracle().getResources()) {
      if (resource.getLastModified() > modificationTime) {
        newerResources.add(resource);
      }
    }

    for (Resource resource : getSourceResourceOracle().getResources()) {
      if (resource.getLastModified() > modificationTime) {
        newerResources.add(resource);
      }
    }

    for (Resource resource : getBuildResourceOracle().getResources()) {
      if (resource.getLastModified() > modificationTime) {
        newerResources.add(resource);
      }
    }

    return newerResources;
  }

  /**
   * Gets a reference to the internal rules for this module def.
   */
  public synchronized Deque<Rule> getRules() {
    return rules;
  }

  /**
   * Gets a reference to the internal scripts list for this module def.
   */
  public Scripts getScripts() {
    return scripts;
  }

  public synchronized String[] getServletPaths() {
    return servletClassNamesByPath.keySet().toArray(Empty.STRINGS);
  }

  @Override
  public Set<String> getSourceModuleNames(String typeSourceName) {
    ensureResourcesScanned();
    return lazySourceOracle.getSourceModulesByTypeSourceName().get(typeSourceName);
  }

  public synchronized ResourceOracle getSourceResourceOracle() {
    ensureResourcesScanned();
    return lazySourceOracle;
  }

  /**
   * Gets a reference to the internal styles list for this module def.
   */
  public Styles getStyles() {
    return styles;
  }

  public boolean isGwtXmlFileStale() {
    return lastModified() > moduleDefCreationTime;
  }

  public boolean isInherited(String moduleName) {
    return inheritedModules.contains(moduleName);
  }

  public long lastModified() {
    long lastModified = 0;
    for (File xmlFile : gwtXmlFiles) {
      if (xmlFile.exists()) {
        lastModified = Math.max(lastModified, xmlFile.lastModified());
      }
    }
    return lastModified > 0 ? lastModified : moduleDefCreationTime;
  }

  /**
   * For convenience in unit tests, servlets can be automatically loaded and
   * mapped in the embedded web server. If a servlet is already mapped to the
   * specified path, it is replaced.
   *
   * @param path the url path at which the servlet resides
   * @param servletClassName the name of the servlet to publish
   */
  public synchronized void mapServlet(String path, String servletClassName) {
    servletClassNamesByPath.put(path, servletClassName);
  }

  public void recordModuleGwtXmlFile(String moduleName, String fileSourcePath) {
    gwtXmlPathByModuleName.put(moduleName, fileSourcePath);
  }

  public synchronized void refresh() {
    resourcesScanned = false;
  }

  /**
   * Mainly for testing and decreasing compile times.
   */
  public void setCollapseAllProperties(boolean collapse) {
    collapseAllProperties = collapse;
  }

  /**
   * Override the module's apparent name. Setting this value to
   * <code>null<code>will disable the name override.
   */
  public synchronized void setNameOverride(String nameOverride) {
    this.nameOverride = nameOverride;
  }

  void addBindingPropertyDefinedValue(BindingProperty bindingProperty, String token) {
    bindingProperty.addDefinedValue(bindingProperty.getRootCondition(), token);
  }

  void addConfigurationPropertyValue(ConfigurationProperty configurationProperty, String value) {
    configurationProperty.addValue(value);
  }

  void addInheritedModules(String moduleName) {
    inheritedModules.add(moduleName);
  }

  /**
   * The final method to call when everything is setup. Before calling this
   * method, several of the getter methods may not be called. After calling this
   * method, the add methods may not be called.
   *
   * @param logger Logs the activity.
   */
  synchronized void normalize(TreeLogger logger) {
    Event moduleDefNormalize =
        SpeedTracerLogger.start(CompilerEventType.MODULE_DEF, "phase", "normalize");

    // Normalize property providers.
    //
    for (BindingProperty prop : properties.getBindingProperties()) {
      if (collapseAllProperties) {
        prop.addCollapsedValues("*");
      }

      prop.normalizeCollapsedValues();

      /*
       * Create a default property provider for any properties with more than
       * one possible value and no existing provider.
       */
      if (prop.getProvider() == null && prop.getConstrainedValue() == null) {
        String src = "{";
        src += "return __gwt_getMetaProperty(\"";
        src += prop.getName();
        src += "\"); }";
        prop.setProvider(new PropertyProvider(src));
      }
    }

    // Create the public path.
    TreeLogger branch = Messages.PUBLIC_PATH_LOCATIONS.branch(logger, null);
    lazyPublicOracle = new ResourceOracleImpl(branch, resources);
    lazyPublicOracle.setPathPrefixes(publicPrefixSet);

    // Create the source path.
    branch = Messages.SOURCE_PATH_LOCATIONS.branch(logger, null);
    lazySourceOracle = new ResourceOracleImpl(branch, resources);
    lazySourceOracle.setPathPrefixes(sourcePrefixSet);

    moduleDefNormalize.end();
  }

  void setConfigurationPropertyValue(ConfigurationProperty configurationProperty, String value) {
    configurationProperty.setValue(value);
  }

  private void checkForSeedTypes(TreeLogger logger, CompilationState compilationState)
      throws UnableToCompleteException {
    // Sanity check the seed types and don't even start it they're missing.
    boolean seedTypesMissing = false;
    TypeOracle typeOracle = compilationState.getTypeOracle();
    if (typeOracle.findType("java.lang.Object") == null) {
      CompilationProblemReporter.logErrorTrace(logger, TreeLogger.ERROR,
          compilationState.getCompilerContext(), "java.lang.Object", true);
      seedTypesMissing = true;
    } else {
      TreeLogger branch = logger.branch(TreeLogger.TRACE, "Finding entry point classes", null);
      String[] typeNames = getEntryPointTypeNames();
      for (int i = 0; i < typeNames.length; i++) {
        String typeName = typeNames[i];
        if (typeOracle.findType(typeName) == null) {
          CompilationProblemReporter.logErrorTrace(branch, TreeLogger.ERROR,
              compilationState.getCompilerContext(), typeName, true);
          seedTypesMissing = true;
        }
      }
    }

    if (seedTypesMissing) {
      throw new UnableToCompleteException();
    }
  }

  private synchronized void ensureResourcesScanned() {
    if (resourcesScanned) {
      return;
    }
    resourcesScanned = true;

    Event moduleDefEvent = SpeedTracerLogger.start(
        CompilerEventType.MODULE_DEF, "phase", "refresh", "module", getName());
    if (lazyResourcesOracle != null) {
      lazyResourcesOracle.scanResources(TreeLogger.NULL);
    }
    lazyPublicOracle.scanResources(TreeLogger.NULL);
    lazySourceOracle.scanResources(TreeLogger.NULL);
    moduleDefEvent.end();
  }

  private String getCurrentLibraryModuleName() {
    return currentLibraryModuleNames.isEmpty() ? "" : currentLibraryModuleNames.peek();
  }
}
