/*
 * Copyright 2011 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.javac;

import com.google.gwt.core.ext.TreeLogger;
import com.google.gwt.core.ext.UnableToCompleteException;
import com.google.gwt.dev.javac.MemoryUnitCache.UnitCacheEntry;
import com.google.gwt.thirdparty.guava.common.collect.Maps;

import java.util.Map;

/**
 * This cache stores {@link CompilationUnit} instances in a Map.
 *
 * Only one unit is cached per resource path. If the contentId of the unit
 * changes, the old unit is discarded and replaced with the new unit.
 */
public class MemoryUnitCache implements UnitCache {
  /**
   * Storage for a compilation unit in the map.
   */
  protected static class UnitCacheEntry {
    private final UnitOrigin origin;
    private final CompilationUnit unit;

    protected UnitCacheEntry(CompilationUnit unit, UnitOrigin source) {
      this.unit = unit;
      this.origin = source;
    }

    public UnitOrigin getOrigin() {
      return origin;
    }

    public CompilationUnit getUnit() {
      return unit;
    }
  }

  /**
   * Track how the unit was loaded. Useful in {@link PersistentUnitCache} for
   * consolidating old cache files.
   *
   */
  protected static enum UnitOrigin {
    /**
     * Unit was loaded from persistent store.
     */
    PERSISTENT,

    /**
     * Unit was introduced by an add due to a run-time compile.
     */
    RUN_TIME
  }

  /**
   * References to all {@link CompilationUnit} objects loaded from the
   * persistent store, and any new ones added to the store as well.
   *
   * The key is resource path.
   */
  protected final Map<String, UnitCacheEntry> unitMap = Maps.newHashMap();

  /**
   * References {@link CompilationUnit} objects by {@link ContentId}, which is
   * composed of the type name and a hash on the source code contents.
   */
  protected final Map<ContentId, UnitCacheEntry> unitMapByContentId = Maps.newHashMap();

  /**
   * Adds a new entry into the cache.
   */
  @Override
  public void add(CompilationUnit newUnit) {
    UnitCacheEntry newEntry = new UnitCacheEntry(newUnit, UnitOrigin.RUN_TIME);
    String resourcePath = newUnit.getResourcePath();
    UnitCacheEntry oldEntry = unitMap.get(resourcePath);
    if (oldEntry != null) {
      remove(oldEntry.getUnit());
    }
    unitMap.put(resourcePath, newEntry);
    unitMapByContentId.put(newUnit.getContentId(), newEntry);
  }

  /**
   * This method is a no-op for an in-memory cache.
   */
  @Override
  public synchronized void cleanup(final TreeLogger logger) {
    // do nothing.
  }

  @Override
  public void clear() throws UnableToCompleteException {
    unitMap.clear();
    unitMapByContentId.clear();
  }

  @Override
  public CompilationUnit find(ContentId contentId) {
    UnitCacheEntry entry = unitMapByContentId.get(contentId);
    if (entry != null) {
      return entry.getUnit();
    }
    return null;
  }

  @Override
  public CompilationUnit find(String resourcePath) {
    UnitCacheEntry entry = unitMap.get(resourcePath);
    if (entry != null) {
      return entry.getUnit();
    }
    return null;
  }

  @Override
  public void remove(CompilationUnit unit) {
    unitMap.remove(unit.getResourcePath());
    unitMapByContentId.remove(unit.getContentId());
  }
}
