/*
 * Copyright 2009 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.resources.css;

import com.google.gwt.core.ext.TreeLogger;
import com.google.gwt.core.ext.typeinfo.JMethod;
import com.google.gwt.resources.client.CssResource.ClassName;
import com.google.gwt.resources.css.ast.Context;
import com.google.gwt.resources.css.ast.CssCompilerException;
import com.google.gwt.resources.css.ast.CssDef;
import com.google.gwt.resources.css.ast.CssSelector;
import com.google.gwt.resources.css.ast.CssStylesheet;
import com.google.gwt.resources.css.ast.CssVisitor;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.IdentityHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.regex.Matcher;

/**
 * Renames class selectors to their obfuscated names.
 */
public class ClassRenamer extends CssVisitor {

  /**
   * A tag to indicate that an externally-defined CSS class has no JMethod that
   * is used to access it.
   */
  private static final Replacement UNREFERENCED_EXTERNAL = new Replacement(
      null, null);

  /*
   * TODO: Replace with Pair<A, B>.
   */
  private static class Replacement {

    private JMethod method;
    private String obfuscatedClassName;

    public Replacement(JMethod method, String obfuscatedClassName) {
      this.method = method;
      this.obfuscatedClassName = obfuscatedClassName;
    }

    public JMethod getMethod() {
      return method;
    }

    public String getObfuscatedClassName() {
      return obfuscatedClassName;
    }

    /**
     * For debugging use only.
     */
    public String toString() {
      if (this == UNREFERENCED_EXTERNAL) {
        return "Unreferenced external class name";
      } else {
        return method.getName() + "=" + obfuscatedClassName;
      }
    }
  }

  /**
   * Records replacements that have actually been performed.
   */
  private final Map<JMethod, String> actualReplacements = new IdentityHashMap<JMethod, String>();
  private final Set<String> cssDefs = new HashSet<String>();

  /**
   * The task-list of replacements to perform in the stylesheet.
   */
  private final Map<String, Replacement> potentialReplacements;
  private final TreeLogger logger;
  private final Set<JMethod> missingClasses;
  private final boolean strict;
  private final Set<String> unknownClasses = new HashSet<String>();

  public ClassRenamer(TreeLogger logger,
      Map<String, Map<JMethod, String>> classReplacementsWithPrefix,
      boolean strict, Set<String> externalClasses) {
    this.logger = logger.branch(TreeLogger.DEBUG, "Replacing CSS class names");
    this.strict = strict;

    potentialReplacements = computeReplacements(classReplacementsWithPrefix,
        externalClasses);

    // Require a definition for all classes in the default namespace
    assert classReplacementsWithPrefix.containsKey("");
    missingClasses = new HashSet<JMethod>(
        classReplacementsWithPrefix.get("").keySet());
  }

  @Override
  public void endVisit(CssDef x, Context ctx) {
    cssDefs.add(x.getKey());
  }

  @Override
  public void endVisit(CssSelector x, Context ctx) {

    String sel = x.getSelector();
    int originalLength = sel.length();

    Matcher ma = CssSelector.CLASS_SELECTOR_PATTERN.matcher(sel);
    StringBuilder sb = new StringBuilder(originalLength);
    int start = 0;

    while (ma.find()) {
      String sourceClassName = ma.group(1);

      Replacement entry = potentialReplacements.get(sourceClassName);

      if (entry == null) {
        unknownClasses.add(sourceClassName);
        continue;

      } else if (entry == UNREFERENCED_EXTERNAL) {
        // An @external without an accessor method. This is OK.
        continue;
      }

      JMethod method = entry.getMethod();
      String obfuscatedClassName = entry.getObfuscatedClassName();

      // Consume the interstitial portion of the original selector
      sb.append(sel.subSequence(start, ma.start(1)));
      sb.append(obfuscatedClassName);
      start = ma.end(1);

      actualReplacements.put(method, obfuscatedClassName);
      missingClasses.remove(method);
    }

    if (start != 0) {
      // Consume the remainder and update the selector
      sb.append(sel.subSequence(start, originalLength));
      x.setSelector(sb.toString());
    }
  }

  @Override
  public void endVisit(CssStylesheet x, Context ctx) {
    boolean stop = false;

    // Skip names corresponding to @def entries. They too can be declared as
    // String accessors.
    List<JMethod> toRemove = new ArrayList<JMethod>();
    for (JMethod method : missingClasses) {
      if (cssDefs.contains(method.getName())) {
        toRemove.add(method);
      }
    }
    for (JMethod method : toRemove) {
      missingClasses.remove(method);
    }

    if (!missingClasses.isEmpty()) {
      stop = true;
      TreeLogger errorLogger = logger.branch(TreeLogger.INFO,
          "The following obfuscated style classes were missing from "
              + "the source CSS file:");
      for (JMethod m : missingClasses) {
        String name = m.getName();
        ClassName className = m.getAnnotation(ClassName.class);
        if (className != null) {
          name = className.value();
        }
        errorLogger.log(TreeLogger.ERROR, name + ": Fix by adding ." + name
            + "{}");
      }
    }

    if (strict && !unknownClasses.isEmpty()) {
      stop = true;
      TreeLogger errorLogger = logger.branch(TreeLogger.ERROR,
          "The following unobfuscated classes were present in a strict CssResource:");
      for (String s : unknownClasses) {
        errorLogger.log(TreeLogger.ERROR, s);
      }
      errorLogger.log(TreeLogger.INFO, "Fix by adding String accessor "
          + "method(s) to the CssResource interface for obfuscated classes, "
          + "or using an @external declaration for unobfuscated classes.");
    }

    if (stop) {
      throw new CssCompilerException("Missing a CSS replacement");
    }
  }

  /**
   * Reports the replacements that were actually performed by this visitor.
   */
  public Map<JMethod, String> getReplacements() {
    return actualReplacements;
  }

  /**
   * Flatten class name lookups to speed selector rewriting.
   * 
   * @param classReplacementsWithPrefix a map of local prefixes to the
   *          obfuscated names of imported methods. If a CssResource makes use
   *          of the {@link CssResource.Import} annotation, the keys of this map
   *          will correspond to the {@link CssResource.ImportedWithPrefix}
   *          value defined on the imported CssResource. The zero-length string
   *          key holds the obfuscated names for the CssResource that is being
   *          generated.
   * @return A flattened version of the classReplacementWithPrefix map, where
   *         the keys are the source class name (with prefix included), and
   *         values have the obfuscated class name and associated JMethod.
   */
  private Map<String, Replacement> computeReplacements(
      Map<String, Map<JMethod, String>> classReplacementsWithPrefix,
      Set<String> externalClasses) {

    Map<String, Replacement> toReturn = new HashMap<String, Replacement>();

    for (String externalClass : externalClasses) {
      toReturn.put(externalClass, UNREFERENCED_EXTERNAL);
    }

    for (Map.Entry<String, Map<JMethod, String>> outerEntry : classReplacementsWithPrefix.entrySet()) {
      String prefix = outerEntry.getKey();

      for (Map.Entry<JMethod, String> entry : outerEntry.getValue().entrySet()) {
        JMethod method = entry.getKey();
        String sourceClassName = method.getName();
        String obfuscatedClassName = entry.getValue();

        ClassName className = method.getAnnotation(ClassName.class);
        if (className != null) {
          sourceClassName = className.value();
        }

        sourceClassName = prefix + sourceClassName;

        if (externalClasses.contains(sourceClassName)) {
          /*
           * It simplifies the sanity-checking logic to treat external classes
           * as though they were simply obfuscated to exactly the value the user
           * wants.
           */
          obfuscatedClassName = sourceClassName;
        }

        toReturn.put(sourceClassName, new Replacement(method,
            obfuscatedClassName));
      }
    }
    return Collections.unmodifiableMap(toReturn);
  }
}
