// 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.query2.engine;

import com.google.common.base.Preconditions;
import com.google.devtools.build.lib.query2.engine.QueryEnvironment.QueryTaskFuture;
import java.util.Collection;
import java.util.Set;

/**
 * A literal set of targets, using 'blaze build' syntax.  Or, a reference to a
 * variable name.  (The syntax of the string "pattern" determines which.)
 *
 * TODO(bazel-team): Perhaps we should distinguish NAME from WORD in the parser,
 * based on the characters in it?  Also, perhaps we should not allow NAMEs to
 * be quoted like WORDs can be.
 *
 * <pre>expr ::= NAME | WORD</pre>
 */
public final class TargetLiteral extends QueryExpression {

  private final String pattern;

  public TargetLiteral(String pattern) {
    this.pattern = Preconditions.checkNotNull(pattern);
  }

  public String getPattern() {
    return pattern;
  }

  public boolean isVariableReference() {
    return LetExpression.isValidVarReference(pattern);
  }

  private <T> QueryTaskFuture<Void> evalVarReference(
      QueryEnvironment<T> env, QueryExpressionContext<T> context, Callback<T> callback) {
    String varName = LetExpression.getNameFromReference(pattern);
    Set<T> value = context.get(varName);
    if (value == null) {
      return env.immediateFailedFuture(
          new QueryException(this, "undefined variable '" + varName + "'"));
    }
    try {
      callback.process(value);
      return env.immediateSuccessfulFuture(null);
    } catch (QueryException e) {
      return env.immediateFailedFuture(e);
    } catch (InterruptedException e) {
      return env.immediateCancelledFuture();
    }
  }

  @Override
  public <T> QueryTaskFuture<Void> eval(
      QueryEnvironment<T> env, QueryExpressionContext<T> context, Callback<T> callback) {
    if (isVariableReference()) {
      return evalVarReference(env, context, callback);
    } else {
      return env.getTargetsMatchingPattern(this, pattern, callback);
    }
  }

  @Override
  public void collectTargetPatterns(Collection<String> literals) {
    if (!isVariableReference()) {
      literals.add(pattern);
    }
  }

  @Override
  public <T, C> T accept(QueryExpressionVisitor<T, C> visitor, C context) {
    return visitor.visit(this, context);
  }

  @Override
  public String toString() {
    // Keep predicate consistent with Lexer.scanWord!
    boolean needsQuoting = Lexer.isReservedWord(pattern)
                        || pattern.isEmpty()
                        || "$-*".indexOf(pattern.charAt(0)) != -1;
    return needsQuoting ? ("\"" + pattern + "\"") : pattern;
  }
}
