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

import com.google.gwt.core.ext.CachedGeneratorResult;
import com.google.gwt.core.ext.PropertyOracle;
import com.google.gwt.core.ext.RebindMode;
import com.google.gwt.core.ext.RebindResult;
import com.google.gwt.core.ext.RebindRuleResolver;
import com.google.gwt.core.ext.TreeLogger;
import com.google.gwt.core.ext.UnableToCompleteException;
import com.google.gwt.core.ext.linker.ArtifactSet;
import com.google.gwt.dev.RebindCache;
import com.google.gwt.dev.cfg.Rule;
import com.google.gwt.dev.javac.CachedGeneratorResultImpl;
import com.google.gwt.dev.javac.StandardGeneratorContext;
import com.google.gwt.dev.jdt.RebindOracle;
import com.google.gwt.dev.util.log.speedtracer.DevModeEventType;
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.collect.Maps;

import java.util.Deque;
import java.util.Map;

/**
 * Implements rebind logic in terms of a variety of other well-known oracles.
 */
public class StandardRebindOracle implements RebindOracle {

  /**
   * Makes the actual deferred binding decision by examining rules.
   */
  private final class Rebinder implements RebindRuleResolver {

    @Override
    public boolean checkRebindRuleResolvable(String typeName) {
      try {
        if (getRebindRule(TreeLogger.NULL, typeName) != null) {
          return true;
        }
      } catch (UnableToCompleteException utcEx) {
      }
      return false;
    }

    public String rebind(TreeLogger logger, String typeName, ArtifactAcceptor artifactAcceptor)
        throws UnableToCompleteException {
      Event rebindEvent = SpeedTracerLogger.start(DevModeEventType.REBIND, "Type Name", typeName);
      try {
        genCtx.setPropertyOracle(propOracle);
        genCtx.setRebindRuleResolver(this);
        Rule rule = getRebindRule(logger, typeName);

        if (rule == null) {
          return typeName;
        }

        CachedGeneratorResult cachedResult = rebindCacheGet(rule, typeName);
        if (cachedResult != null) {
          genCtx.setCachedGeneratorResult(cachedResult);
        }

        // realize the rule (call a generator, or do type replacement, etc.)
        RebindResult result = rule.realize(logger, genCtx, typeName);

        // handle rebind result caching (if enabled)
        String resultTypeName =
            processCacheableResult(logger, rule, typeName, cachedResult, result);

        /*
         * Finalize new artifacts from the generator context
         */
        if (artifactAcceptor != null) {
          // Go ahead and call finish() to accept new artifacts.
          ArtifactSet newlyGeneratedArtifacts = genCtx.finish(logger);
          if (!newlyGeneratedArtifacts.isEmpty()) {
            artifactAcceptor.accept(logger, newlyGeneratedArtifacts);
          }
        }

        assert (resultTypeName != null);
        return resultTypeName;
      } finally {
        rebindEvent.end();
      }
    }

    private Rule getRebindRule(TreeLogger logger, String typeName) throws UnableToCompleteException {

      // Make the rebind decision.
      if (rules.isEmpty()) {
        logger.log(TreeLogger.DEBUG, "No rules are defined, so no substitution can occur", null);
        return null;
      }

      Rule minCostRuleSoFar = null;

      for (Rule rule : rules) {

        TreeLogger branch = Messages.TRACE_CHECKING_RULE.branch(logger, rule, null);

        if (rule.isApplicable(branch, genCtx, typeName)) {
          Messages.TRACE_RULE_MATCHED.log(logger, null);
          return rule;
        }
        Messages.TRACE_RULE_DID_NOT_MATCH.log(logger, null);

        // keep track of fallback partial matches
        if (minCostRuleSoFar == null) {
          minCostRuleSoFar = rule;
        }
        assert rule.getFallbackEvaluationCost() != 0;
        // if we found a better match, keep that as the best candidate so far
        if (rule.getFallbackEvaluationCost() <= minCostRuleSoFar.getFallbackEvaluationCost()) {
          if (logger.isLoggable(TreeLogger.DEBUG)) {
            logger.log(TreeLogger.DEBUG, "Found better fallback match for " + rule);
          }
          minCostRuleSoFar = rule;
        }
      }

      // if we reach this point, it means we did not find an exact match
      // and we may have a partial match based on fall back values
      assert minCostRuleSoFar != null;
      if (minCostRuleSoFar.getFallbackEvaluationCost() < Integer.MAX_VALUE) {
        if (logger.isLoggable(TreeLogger.INFO)) {
          logger.log(TreeLogger.INFO, "Could not find an exact match rule. Using 'closest' rule "
              + minCostRuleSoFar
              + " based on fall back values. You may need to implement a specific "
              + "binding in case the fall back behavior does not replace the missing binding");
        }
        if (logger.isLoggable(TreeLogger.DEBUG)) {
          logger.log(TreeLogger.DEBUG, "No exact match was found, using closest match rule "
              + minCostRuleSoFar);
        }
        return minCostRuleSoFar;
      }

      // No matching rule for this type.
      return null;
    }

    /*
     * Decide how to handle integrating a previously cached result, and whether
     * to cache the new result for the future.
     */
    private String processCacheableResult(TreeLogger logger, Rule rule, String typeName,
        CachedGeneratorResult cachedResult, RebindResult newResult) {

      String resultTypeName = newResult.getResultTypeName();

      if (!genCtx.isGeneratorResultCachingEnabled()) {
        return resultTypeName;
      }

      RebindMode mode = newResult.getRebindMode();
      switch (mode) {

        case USE_EXISTING:
          // in this case, no newly generated or cached types are needed
          break;

        case USE_ALL_NEW_WITH_NO_CACHING:
          /*
           * in this case, new artifacts have been generated, but no need to
           * cache results (as the generator is probably not able to take
           * advantage of caching).
           */
          break;

        case USE_ALL_NEW:
          // use all new results, add a new cache entry
          cachedResult =
              new CachedGeneratorResultImpl(newResult.getResultTypeName(), genCtx.getArtifacts(),
                  genCtx.getGeneratedUnitMap(), System.currentTimeMillis(), newResult
                      .getClientDataMap());
          rebindCachePut(rule, typeName, cachedResult);
          break;

        case USE_ALL_CACHED:
          // use all cached results
          assert (cachedResult != null);

          genCtx.commitArtifactsFromCache(logger);
          genCtx.addGeneratedUnitsFromCache();

          // use cached type name
          resultTypeName = cachedResult.getResultTypeName();
          break;

        case USE_PARTIAL_CACHED:
          /*
           * Add cached generated units marked for reuse to the context.
           * TODO(jbrosenberg): add support for reusing artifacts as well as
           * GeneratedUnits.
           */
          genCtx.addGeneratedUnitsMarkedForReuseFromCache();

          /*
           * Create a new cache entry using the composite set of new and reused
           * cached results currently in genCtx.
           */
          cachedResult =
              new CachedGeneratorResultImpl(newResult.getResultTypeName(), genCtx.getArtifacts(),
                  genCtx.getGeneratedUnitMap(), System.currentTimeMillis(), newResult
                      .getClientDataMap());
          rebindCachePut(rule, typeName, cachedResult);
          break;
      }

      // clear the current cached result
      genCtx.setCachedGeneratorResult(null);

      return resultTypeName;
    }
  }

  private final Map<String, String> typeNameBindingMap = Maps.newHashMap();

  private final StandardGeneratorContext genCtx;

  private final PropertyOracle propOracle;

  private RebindCache rebindCache = null;

  private final Deque<Rule> rules;

  public StandardRebindOracle(PropertyOracle propOracle, Deque<Rule> rules,
      StandardGeneratorContext genCtx) {
    this.propOracle = propOracle;
    this.rules = rules;
    this.genCtx = genCtx;
  }

  @Override
  public String rebind(TreeLogger logger, String typeName) throws UnableToCompleteException {
    return rebind(logger, typeName, null);
  }

  public String rebind(TreeLogger logger, String typeName, ArtifactAcceptor artifactAcceptor)
      throws UnableToCompleteException {

    String resultTypeName = typeNameBindingMap.get(typeName);
    if (resultTypeName == null) {
      logger = Messages.TRACE_TOPLEVEL_REBIND.branch(logger, typeName, null);

      Rebinder rebinder = new Rebinder();
      resultTypeName = rebinder.rebind(logger, typeName, artifactAcceptor);
      typeNameBindingMap.put(typeName, resultTypeName);

      Messages.TRACE_TOPLEVEL_REBIND_RESULT.log(logger, resultTypeName, null);
    }
    return resultTypeName;
  }

  public void setRebindCache(RebindCache cache) {
    this.rebindCache = cache;
  }

  private CachedGeneratorResult rebindCacheGet(Rule rule, String typeName) {
    if (rebindCache != null) {
      return rebindCache.get(rule, typeName);
    }
    return null;
  }

  private void rebindCachePut(Rule rule, String typeName, CachedGeneratorResult result) {
    if (rebindCache != null) {
      rebindCache.put(rule, typeName, result);
    }
  }
}
