/*
 * 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.thirdparty.guava.common.base.Charsets;
import com.google.gwt.thirdparty.guava.common.collect.Sets;
import com.google.gwt.thirdparty.guava.common.io.Resources;

import java.io.IOException;
import java.net.URL;
import java.util.List;
import java.util.Set;

/**
 * Determines whether or not a particular string is a JavaScript keyword or an illegal name.
 */
public class JsProtectedNames {

  private static final Set<String> illegalNames;

  static {
    illegalNames = Sets.newHashSet(
        // These are current keywords as of ES6
        "break", "case", "class", "catch", "const", "continue", "debugger", "default", "delete",
        "do", "else", "export", "extends", "finally", "for", "function", "if", "import", "in",
        "instanceof", "let", "new", "return", "super", "switch", "this", "throw", "try", "typeof",
        "var", "void", "while", "with", "yield",

        // Future reserved keywords
        "abstract", "arguments", "async", "await",  "boolean", "byte", "char", "double", "false",
        "final", "float", "goto", "implements", "int",  "interface", "long", "native", "null",
        "package", "private", "protected", "public", "short", "static", "synchronized", "throws",
        "transient", "true", "volatile",

        // These might be top level variables or functions that we care not to hide. Grabbed from
        // closure externs es?.js, w3c_d*.js and window.js.
        //
        // TODO(rluble): Javascript code generated by GWT should always define a closure to
        // to ensure that top level symbols do not get redefined and also to ensure that
        // declaring a global variable using "var" is enough to guarantee that the variable is
        // is undefined regardless whether a variable/function with the same name exists at the
        // top scope.
        "body", "click", "min", "bind", "watch", "set", "ch", "code", "bold", "Date", "Text",
        "color", "event", "Attr", "sin", "exec", "quote", "form", "add", "isMap", "width", "alert",
        "java", "big", "parse", "media", "floor", "abbr", "gamma", "id", "dump", "exp", "some",
        "link", "abs", "self", "tan", "test", "every", "isNaN", "index", "pop", "join", "fixed",
        "ceil", "span", "UTC", "SQRT2", "name", "tFoot", "pow", "URL", "face", "sub", "vLink",
        "label", "cells", "rows", "eval", "cols", "acos", "lang", "trim", "LN10", "cite", "frame",
        "sun", "links", "sup", "areas", "isId", "type", "seal", "shift", "keys", "call", "close",
        "axis", "alt", "uri", "value", "rules", "reset", "alpha", "E", "open", "aLink", "sheet",
        "start", "Node", "blink", "stack", "now", "slice", "clear", "rel", "top", "scope", "item",
        "sqrt", "LOG2E", "align", "href", "apply", "chOff", "Array", "rev", "asin", "tHead",
        "match", "src", "cos", "title", "write", "JSON", "PI", "beta", "log", "forms", "split",
        "input", "NaN", "focus", "map", "defer", "data", "push", "atan2", "atan", "shape", "small",
        "blur", "text", "LN2", "get", "max", "arity", "dir", "x", "Error", "y", "z", "sort", "size",
        "round", "Math", "undefined",
        // From Chrome 30
        "CSS", "Rect", "Blob", "self", "Node", "JSON", "Intl", "Attr", "Date",
        "File", "name", "Text", "Array", "Audio", "event", "Range", "Touch", "Image", "Error",
        "Event", "top", "url",
        // From Firefox 25
        "Map", "Set", "Proxy",
        // From Safari 7.0
        "Path", "self");

    illegalNames.addAll(loadGlobals("chrome"));
    illegalNames.addAll(loadGlobals("firefox25"));
    illegalNames.addAll(loadGlobals("ie9"));
    // Impl.getHashCode
    illegalNames.add("$H");
  }

  /**
   * Loads globals from a resource file in the "globals" subdirectory.
   */
  private static List<String> loadGlobals(String basename) {
    String path = "globals/" + basename + ".txt";
    URL resource = JsProtectedNames.class.getResource(path);
    if (resource == null) {
      throw new RuntimeException("JsProtectedNames can't find resource: " + path);
    }
    try {
      return Resources.readLines(resource, Charsets.UTF_8);
    } catch (IOException e) {
      throw new RuntimeException("JsProtectedNames can't read resource: " + path, e);
    }
  }

  public static boolean isLegalName(String s) {
    return !illegalNames.contains(s);
  }

  private JsProtectedNames() {
  }
}
