/*
 * Copyright 2007 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.js;

import com.google.gwt.dev.cfg.ConfigurationProperties;
import com.google.gwt.dev.js.ast.JsName;
import com.google.gwt.dev.js.ast.JsProgram;
import com.google.gwt.dev.js.ast.JsScope;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Set;

/**
 * A namer that keeps the short ("pretty") identifier wherever possible.
 */
public class JsPrettyNamer extends JsNamer {

  public static void exec(JsProgram program, ConfigurationProperties config) throws IllegalNameException {
    new JsPrettyNamer(program, config).execImpl();
  }

  public JsPrettyNamer(JsProgram program, ConfigurationProperties config) {
    super(program, config);
  }

  @Override
  protected void reset() {
  }

  @Override
  protected void visit(JsScope scope) {
    changeNames(scope);
  }

  /**
   * Does a minimal fixup on the short names in the given scope and all its descendants.
   * Unobfuscatable names map to their full name and any names that conflict with a previous
   * idenitifier or any child scope's identifier are renamed. Otherwise the short name is
   * left as-is.
   * @return all names used in the given scope and any of its descendants (after renaming).
   */
  private Set<String> changeNames(JsScope scope) {

    // First, change the names in all the child scopes and remember that they're taken.
    Set<String> taken = new HashSet<String>();
    for (JsScope child : scope.getChildren()) {
      taken.addAll(changeNames(child));
    }

    // The next integer to try as an identifier suffix.
    HashMap<String, Integer> suffixCounters = new HashMap<String, Integer>();

    for (JsName name : scope.getAllNames()) {
      if (!referenced.contains(name)) {
        // Don't allocate idents for non-referenced names.
        continue;
      }
      rename(name, scope, taken, suffixCounters);
      taken.add(name.getShortIdent());
    }

    return taken;
  }

  /**
   * Changes the short identifier of one JsName.
   * @param taken the set of short identifiers that are already used (read-only)
   * @param suffixCounters contains the next suffix to use for each prefix (updated).
   */
  private void rename(JsName name, JsScope scope, Set<String> taken,
      HashMap<String, Integer> suffixCounters) {

    if (!name.isObfuscatable()) {
      // We must use the full name.
      name.setShortIdent(name.getIdent());
      return;
    }

    String prefix = name.getShortIdent();
    if (prefix.contains("-")) {
      // Fixes package-info.java classes.
      prefix = prefix.replace("-", "_");
      name.setShortIdent(prefix);
    }
    if (!isAvailable(prefix, scope, taken)) {

      // Start searching using a suffix hint stored in the scope.
      // We still do a search in case there is a collision with
      // a user-provided identifier

      Integer suffixOrNull = suffixCounters.get(prefix);
      int suffix = (suffixOrNull == null) ? 0 : suffixOrNull;

      String candidate;
      do {
        candidate = prefix + "_" + suffix++;
      } while (!isAvailable(candidate, scope, taken));

      suffixCounters.put(prefix, suffix);
      name.setShortIdent(candidate);
    }
    // otherwise the short name is already good
  }

  /**
   * Returns true if a candidate identifier is available in a scope.
   * @param taken the set of names that we've already used.
   */
  private boolean isAvailable(String candidate, JsScope scope, Set<String> taken) {
    if (!reserved.isAvailable(candidate)) {
      return false;
    }

    if (taken.contains(candidate)) {
      return false;
    }
    /*
     * Never obfuscate a name into an identifier that conflicts with an existing
     * unobfuscatable name! It's okay if it conflicts with an existing
     * obfuscatable name; that name will get obfuscated out of the way.
     */
    return (scope.findExistingUnobfuscatableName(candidate) == null);
  }
}
