/*
 * 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) {
      StringBuilder text = new StringBuilder();
      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));
      }
    }
  }
}
