// Copyright 2014 The Bazel Authors. All rights reserved.
//
// 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.devtools.build.lib.syntax;

import com.google.common.base.Preconditions;
import com.google.devtools.build.lib.util.SpellChecker;
import java.io.IOException;
import java.util.Set;
import javax.annotation.Nullable;

// TODO(bazel-team): For performance, avoid doing HashMap lookups at runtime, and compile local
// variable access into array reference with a constant index. Variable lookups are currently a
// speed bottleneck, as previously measured in an experiment.
/**
 * Syntax node for an identifier.
 *
 * <p>Unlike most {@link ASTNode} subclasses, this one supports {@link Object#equals} and {@link
 * Object#hashCode} (but note that these methods ignore location information). They are needed
 * because {@code Identifier}s are stored in maps when constructing {@link LoadStatement}.
 */
public final class Identifier extends Expression {

  private final String name;
  // The scope of the variable. The value is set when the AST has been analysed by
  // ValidationEnvironment.
  @Nullable private ValidationEnvironment.Scope scope;

  public Identifier(String name) {
    this.name = name;
  }

  /**
   *  Returns the name of the Identifier.
   */
  public String getName() {
    return name;
  }

  public boolean isPrivate() {
    return name.startsWith("_");
  }

  @Override
  public void prettyPrint(Appendable buffer) throws IOException {
    buffer.append(name);
  }

  void setScope(ValidationEnvironment.Scope scope) {
    Preconditions.checkState(this.scope == null);
    this.scope = scope;
  }

  @Override
  Object doEval(Environment env) throws EvalException {
    Object result;
    if (scope == null) {
      // Legacy behavior, to be removed.
      result = env.lookup(name);
      if (result == null) {
        throw createInvalidIdentifierException(env.getVariableNames());
      }
      return result;
    }

    switch (scope) {
      case Local:
        result = env.localLookup(name);
        break;
      case Module:
        result = env.moduleLookup(name);
        break;
      case Universe:
        result = env.universeLookup(name);
        break;
      default:
        throw new IllegalStateException(scope.toString());
    }

    if (result == null) {
      // Since Scope was set, we know that the variable is defined in the scope.
      // However, the assignment was not yet executed.
      EvalException e = getSpecialException();
      throw e != null
          ? e
          : new EvalException(
              getLocation(),
              scope.getQualifier() + " variable '" + name + "' is referenced before assignment.");
    }

    return result;
  }

  @Override
  public void accept(SyntaxTreeVisitor visitor) {
    visitor.visit(this);
  }

  @Override
  public Kind kind() {
    return Kind.IDENTIFIER;
  }

  /** Exception to provide a better error message for using PACKAGE_NAME or REPOSITORY_NAME. */
  private EvalException getSpecialException() {
    if (name.equals("PACKAGE_NAME")) {
      return new EvalException(
          getLocation(),
          "The value 'PACKAGE_NAME' has been removed in favor of 'package_name()', "
              + "please use the latter ("
              + "https://docs.bazel.build/versions/master/skylark/lib/native.html#package_name). ");
    }
    if (name.equals("REPOSITORY_NAME")) {
      return new EvalException(
          getLocation(),
          "The value 'REPOSITORY_NAME' has been removed in favor of 'repository_name()', please"
              + " use the latter ("
              + "https://docs.bazel.build/versions/master/skylark/lib/native.html#repository_name).");
    }
    return null;
  }

  EvalException createInvalidIdentifierException(Set<String> symbols) {
    if (name.equals("$error$")) {
      return new EvalException(getLocation(), "contains syntax error(s)", true);
    }

    EvalException e = getSpecialException();
    if (e != null) {
      return e;
    }

    String suggestion = SpellChecker.didYouMean(name, symbols);
    return new EvalException(getLocation(), "name '" + name + "' is not defined" + suggestion);
  }

  /** @return The {@link Identifier} of the provided name. */
  public static Identifier of(String name) {
    return new Identifier(name);
  }

  /** Returns true if the string is a syntactically valid identifier. */
  public static boolean isValid(String name) {
    // TODO(laurentlb): Handle Unicode characters.
    if (name.isEmpty()) {
      return false;
    }
    for (int i = 0; i < name.length(); i++) {
      char c = name.charAt(i);
      if ((c >= 'a' && c <= 'z')
          || (c >= 'A' && c <= 'Z')
          || (c >= '0' && c <= '9')
          || (c == '_')) {
        continue;
      }
      return false;
    }
    if (name.charAt(0) >= '0' && name.charAt(0) <= '9') {
      return false;
    }

    return true;
  }
}
