/*
 * Copyright 2010 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.core.ext.linker.impl;

import com.google.gwt.core.ext.LinkerContext;
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.core.ext.linker.SelectionProperty;
import com.google.gwt.dev.util.StringKey;
import com.google.gwt.dev.util.collect.HashSet;
import com.google.gwt.dev.util.collect.Lists;

import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.SortedMap;
import java.util.TreeMap;

/**
 * A utility class to help linkers generate a list of permutation mappings and
 * and then either output them to javascript code which selects the correct
 * permutation, or to a file which can be parsed by server side code.
 */
public class PermutationsUtil {
  
  /**
   * This represents the combination of a unique content hash (i.e. the MD5 of
   * the bytes to be written into the cache.html file) and a soft permutation
   * id.
   */
  protected static class PermutationId extends StringKey {
    private final int softPermutationId;
    private final String strongName;

    public PermutationId(String strongName, int softPermutationId) {
      super(strongName + ":" + softPermutationId);
      this.strongName = strongName;
      this.softPermutationId = softPermutationId;
    }

    public int getSoftPermutationId() {
      return softPermutationId;
    }

    public String getStrongName() {
      return strongName;
    }
  }

  /**
   * This maps each unique permutation to the property settings for that
   * compilation. A single compilation can have multiple property settings if
   * the compiles for those settings yielded the exact same compiled output.
   */
  protected SortedMap<PermutationId, List<Map<String, String>>> propMapsByPermutation =
      new TreeMap<PermutationId, List<Map<String, String>>>();

  /**
   * Uses the internal map to insert JS to select a permutation into the
   * selection script.
   * 
   * @param selectionScript
   * @param logger
   * @param context
   * @return the modified selectionScript buffer
   * @throws UnableToCompleteException 
   */
  public StringBuffer addPermutationsJs(StringBuffer selectionScript,
      TreeLogger logger, LinkerContext context)
      throws UnableToCompleteException {
    int startPos;
    
    PropertiesUtil.addPropertiesJs(selectionScript, logger, context);

    // Possibly add permutations
    startPos = selectionScript.indexOf("// __PERMUTATIONS_END__");
    if (startPos != -1) {
      StringBuffer text = new StringBuffer();
      if (propMapsByPermutation.size() == 0) {
        // Hosted mode link.
        text.append("alert(\"GWT module '" + context.getModuleName()
            + "' may need to be (re)compiled\");");
        text.append("return;");

      } else if (propMapsByPermutation.size() == 1) {
        // Just one distinct compilation; no need to evaluate properties
        text.append("strongName = '"
            + propMapsByPermutation.keySet().iterator().next().getStrongName()
            + "';");
      } else {
        Set<String> propertiesUsed = new HashSet<String>();
        for (PermutationId permutationId : propMapsByPermutation.keySet()) {
          for (Map<String, String> propertyMap : propMapsByPermutation.get(permutationId)) {
            // unflatten([v1, v2, v3], 'strongName' + ':softPermId');
            // The soft perm ID is concatenated to improve string interning
            text.append("unflattenKeylistIntoAnswers([");
            boolean needsComma = false;
            for (SelectionProperty p : context.getProperties()) {
              if (p.tryGetValue() != null) {
                continue;
              } else if (p.isDerived()) {
                continue;
              }

              if (needsComma) {
                text.append(",");
              } else {
                needsComma = true;
              }
              text.append("'" + propertyMap.get(p.getName()) + "'");
              propertiesUsed.add(p.getName());
            }

            text.append("], '").append(permutationId.getStrongName()).append(
                "'");
            /*
             * For compatibility with older linkers, skip the soft permutation
             * if it's 0
             */
            if (permutationId.getSoftPermutationId() != 0) {
              text.append(" + ':").append(permutationId.getSoftPermutationId()).append(
                  "'");
            }
            text.append(");\n");
          }
        }

        // strongName = answers[compute('p1')][compute('p2')];
        text.append("strongName = answers[");
        boolean needsIndexMarkers = false;
        for (SelectionProperty p : context.getProperties()) {
          if (!propertiesUsed.contains(p.getName())) {
            continue;
          }
          if (needsIndexMarkers) {
            text.append("][");
          } else {
            needsIndexMarkers = true;
          }
          text.append("computePropValue('" + p.getName() + "')");
        }
        text.append("];");
      }
      selectionScript.insert(startPos, text);
    }

    return selectionScript;
  }
  
  public SortedMap<PermutationId, List<Map<String, String>>> getPermutationsMap() {
    return propMapsByPermutation;
  }
  
  /**
   * Find all instances of {@link SelectionInformation} and add them to the
   * internal map of selection information.
   */
  public void setupPermutationsMap(ArtifactSet artifacts) {
    propMapsByPermutation =
      new TreeMap<PermutationId, List<Map<String, String>>>();
    for (SelectionInformation selInfo : artifacts.find(SelectionInformation.class)) {
      TreeMap<String, String> entries = selInfo.getPropMap();
      PermutationId permutationId = new PermutationId(selInfo.getStrongName(),
          selInfo.getSoftPermutationId());
      if (!propMapsByPermutation.containsKey(permutationId)) {
        propMapsByPermutation.put(permutationId,
            Lists.<Map<String, String>> create(entries));
      } else {
        propMapsByPermutation.put(permutationId, Lists.add(
            propMapsByPermutation.get(permutationId), entries));
      }
    }
  }
}
