/*
 * 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.resource.impl;

import com.google.gwt.core.ext.TreeLogger;
import com.google.gwt.dev.util.collect.IdentityHashMap;
import com.google.gwt.dev.util.collect.IdentityHashSet;
import com.google.gwt.dev.util.collect.IdentityMaps;
import com.google.gwt.dev.util.collect.Sets;
import com.google.gwt.dev.util.msg.Message1String;

import org.apache.commons.collections.map.AbstractReferenceMap;
import org.apache.commons.collections.map.ReferenceIdentityMap;
import org.apache.commons.collections.map.ReferenceMap;

import java.io.File;
import java.io.IOException;
import java.util.Enumeration;
import java.util.Map;
import java.util.Set;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;

/**
 * A classpath entry that is a jar or zip file.
 */
public class ZipFileClassPathEntry extends ClassPathEntry {

  /**
   * Logger messages related to this class.
   */
  private static class Messages {
    static final Message1String BUILDING_INDEX = new Message1String(
        TreeLogger.TRACE, "Indexing zip file: $0");

    static final Message1String EXCLUDING_RESOURCE = new Message1String(
        TreeLogger.DEBUG, "Excluding $0");

    static final Message1String FINDING_INCLUDED_RESOURCES = new Message1String(
        TreeLogger.DEBUG, "Searching for included resources in $0");

    static final Message1String INCLUDING_RESOURCE = new Message1String(
        TreeLogger.DEBUG, "Including $0");

    static final Message1String READ_ZIP_ENTRY = new Message1String(
        TreeLogger.DEBUG, "$0");
  }

  private static class ZipFileSnapshot {
    private final Map<AbstractResource, PathPrefix> cachedAnswers;
    private final int prefixSetSize;

    ZipFileSnapshot(int prefixSetSize,
        Map<AbstractResource, PathPrefix> cachedAnswers) {
      this.prefixSetSize = prefixSetSize;
      this.cachedAnswers = cachedAnswers;
    }
  }

  /**
   * Memory-sensitive cache of indexed {@link ZipFileClassPathEntry}s. URI of file is most probably
   * not referenced anywhere else, so we use hard reference, and soft reference on
   * {@link ZipFileClassPathEntry} allows its clearing in response to memory demand.
   */
  @SuppressWarnings("unchecked")
  private static final Map<String, ZipFileClassPathEntry> entryCache = new ReferenceMap(
      AbstractReferenceMap.HARD, AbstractReferenceMap.SOFT);

  /**
   * @return the {@link ZipFileClassPathEntry} instance for given jar or zip
   *         file, may be shared with other users.
   */
  public static synchronized ZipFileClassPathEntry get(File zipFile) throws IOException {
    String location = zipFile.toURI().toString();
    ZipFileClassPathEntry entry = entryCache.get(location);
    if (entry == null) {
      entry = new ZipFileClassPathEntry(zipFile);
      entryCache.put(location, entry);
    }
    return entry;
  }

  private Set<ZipFileResource> allZipFileResources;

  /**
   * The lifetime of the {@link PathPrefixSet} pins the life time of the associated
   * {@link ZipFileSnapshot}; this is because the {@link PathPrefixSet} is referenced from module,
   * and {@link ZipFileSnapshot} is not referenced anywhere outside of {@link ZipFileClassPathEntry}
   * . When the module dies, the {@link ZipFileSnapshot} needs to die also.
   */
  @SuppressWarnings("unchecked")
  private final Map<PathPrefixSet, ZipFileSnapshot> cachedSnapshots = new ReferenceIdentityMap(
      AbstractReferenceMap.WEAK, AbstractReferenceMap.HARD, true);

  private final long lastModified;
  private final String location;
  private final ZipFile zipFile;

  private ZipFileClassPathEntry(File zipFile) throws IOException {
    assert zipFile.isAbsolute();
    this.lastModified = zipFile.lastModified();
    this.zipFile = new ZipFile(zipFile);
    this.location = zipFile.toURI().toString();
  }

  /**
   * Indexes the zip file on-demand, and only once over the life of the process.
   */
  @Override
  public synchronized Map<AbstractResource, PathPrefix> findApplicableResources(
      TreeLogger logger, PathPrefixSet pathPrefixSet) {
    index(logger);
    ZipFileSnapshot snapshot = cachedSnapshots.get(pathPrefixSet);
    if (snapshot == null || snapshot.prefixSetSize != pathPrefixSet.getSize()) {
      snapshot = new ZipFileSnapshot(pathPrefixSet.getSize(),
          computeApplicableResources(logger, pathPrefixSet));
      cachedSnapshots.put(pathPrefixSet, snapshot);
    }
    return snapshot.cachedAnswers;
  }

  @Override
  public String getLocation() {
    return location;
  }

  public ZipFile getZipFile() {
    return zipFile;
  }

  public long lastModified() {
    return lastModified;
  }

  synchronized void index(TreeLogger logger) {
    // Never re-index.
    if (allZipFileResources == null) {
      allZipFileResources = buildIndex(logger);
    }
  }

  private Set<ZipFileResource> buildIndex(TreeLogger logger) {
    logger = Messages.BUILDING_INDEX.branch(logger, zipFile.getName(), null);

    Set<ZipFileResource> results = new IdentityHashSet<ZipFileResource>();
    Enumeration<? extends ZipEntry> e = zipFile.entries();
    while (e.hasMoreElements()) {
      ZipEntry zipEntry = e.nextElement();
      if (zipEntry.isDirectory()) {
        // Skip directories.
        continue;
      }
      if (zipEntry.getName().startsWith("META-INF/")) {
        // Skip META-INF since classloaders normally make this invisible.
        continue;
      }
      ZipFileResource zipResource = new ZipFileResource(this,
          zipEntry.getName());
      results.add(zipResource);
      Messages.READ_ZIP_ENTRY.log(logger, zipEntry.getName(), null);
    }
    return Sets.normalize(results);
  }

  private Map<AbstractResource, PathPrefix> computeApplicableResources(
      TreeLogger logger, PathPrefixSet pathPrefixSet) {
    logger = Messages.FINDING_INCLUDED_RESOURCES.branch(logger,
        zipFile.getName(), null);

    Map<AbstractResource, PathPrefix> results = new IdentityHashMap<AbstractResource, PathPrefix>();
    for (ZipFileResource r : allZipFileResources) {
      String path = r.getPath();
      String[] pathParts = r.getPathParts();
      PathPrefix prefix = null;
      if ((prefix = pathPrefixSet.includesResource(path, pathParts)) != null) {
        Messages.INCLUDING_RESOURCE.log(logger, path, null);
        results.put(r, prefix);
      } else {
        Messages.EXCLUDING_RESOURCE.log(logger, path, null);
      }
    }
    return IdentityMaps.normalize(results);
  }
}
