// 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 static com.google.devtools.build.lib.syntax.compiler.ByteCodeUtils.append;

import com.google.devtools.build.lib.events.Location;
import com.google.devtools.build.lib.syntax.compiler.ByteCodeUtils;
import com.google.devtools.build.lib.syntax.compiler.DebugInfo.AstAccessors;
import com.google.devtools.build.lib.syntax.compiler.Variable.InternalVariable;
import com.google.devtools.build.lib.syntax.compiler.VariableScope;
import com.google.devtools.build.lib.util.Preconditions;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import net.bytebuddy.implementation.bytecode.ByteCodeAppender;
import net.bytebuddy.implementation.bytecode.Removal;
import net.bytebuddy.implementation.bytecode.constant.IntegerConstant;

/**
 * Class representing an LValue.
 * It appears in assignment, for loop and comprehensions, e.g.
 *    lvalue = 2
 *    [for lvalue in exp]
 *    for lvalue in exp: pass
 * An LValue can be a simple variable or something more complex like a tuple.
 */
public class LValue implements Serializable {
  private final Expression expr;

  public LValue(Expression expr) {
    this.expr = expr;
  }

  public Expression getExpression() {
    return expr;
  }

  /**
   * Assign a value to an LValue and update the environment.
   */
  public void assign(Environment env, Location loc, Object result)
      throws EvalException, InterruptedException {
    assign(env, loc, expr, result);
  }

  private static void assign(Environment env, Location loc, Expression lvalue, Object result)
      throws EvalException, InterruptedException {
    if (lvalue instanceof Identifier) {
      assign(env, loc, (Identifier) lvalue, result);
      return;
    }

    if (lvalue instanceof ListLiteral) {
      ListLiteral variables = (ListLiteral) lvalue;
      Collection<?> rvalue = EvalUtils.toCollection(result, loc);
      int len = variables.getElements().size();
      if (len != rvalue.size()) {
        throw new EvalException(loc, String.format(
            "lvalue has length %d, but rvalue has has length %d", len, rvalue.size()));
      }
      int i = 0;
      for (Object o : rvalue) {
        assign(env, loc, variables.getElements().get(i), o);
        i++;
      }
      return;
    }

    // Support syntax for setting an element in an array, e.g. a[5] = 2
    // TODO: We currently do not allow slices (e.g. a[2:6] = [3]).
    if (lvalue instanceof IndexExpression) {
      IndexExpression expression = (IndexExpression) lvalue;
      Object key = expression.getKey().eval(env);
      Object evaluatedObject = expression.getObject().eval(env);
      assignItem(env, loc, evaluatedObject, key, result);
      return;
    }
    throw new EvalException(loc,
        "can only assign to variables and tuples, not to '" + lvalue + "'");
  }

  @SuppressWarnings("unchecked")
  private static void assignItem(
      Environment env, Location loc, Object o, Object key, Object value)
      throws EvalException, InterruptedException {
    if (o instanceof SkylarkDict) {
      SkylarkDict<Object, Object> dict = (SkylarkDict<Object, Object>) o;
      dict.put(key, value, loc, env);
    } else if (o instanceof  SkylarkList) {
      SkylarkList<Object> list = (SkylarkList<Object>) o;
      list.set(key, value, loc, env);
    } else {
      throw new EvalException(
          loc,
          "can only assign an element in a dictionary or a list, not in a '"
              + EvalUtils.getDataTypeName(o)
              + "'");
    }
  }

  /**
   * Assign value to a single variable.
   */
  private static void assign(Environment env, Location loc, Identifier ident, Object result)
      throws EvalException, InterruptedException {
    Preconditions.checkNotNull(result, "trying to assign null to %s", ident);

    // The variable may have been referenced successfully if a global variable
    // with the same name exists. In this case an Exception needs to be thrown.
    if (env.isKnownGlobalVariable(ident.getName())) {
      throw new EvalException(
          loc,
          String.format(
              "Variable '%s' is referenced before assignment. "
                  + "The variable is defined in the global scope.",
              ident.getName()));
    }
    env.update(ident.getName(), result);
  }

  void validate(ValidationEnvironment env, Location loc) throws EvalException {
    validate(env, loc, expr);
  }

  private static void validate(ValidationEnvironment env, Location loc, Expression expr)
      throws EvalException {
    if (expr instanceof Identifier) {
      Identifier ident = (Identifier) expr;
      env.declare(ident.getName(), loc);
      return;
    }
    if (expr instanceof ListLiteral) {
      for (Expression e : ((ListLiteral) expr).getElements()) {
        validate(env, loc, e);
      }
      return;
    }
    if (expr instanceof IndexExpression) {
      expr.validate(env);
      return;
    }
    throw new EvalException(loc,
        "can only assign to variables and tuples, not to '" + expr + "'");
  }

  @Override
  public String toString() {
    return expr.toString();
  }

  /**
   * Compile an assignment within the given ASTNode to these l-values.
   *
   * <p>The value to possibly destructure and assign must already be on the stack.
   */
  public ByteCodeAppender compileAssignment(
      ASTNode node, AstAccessors debugAccessors, VariableScope scope) throws EvalException {
    List<ByteCodeAppender> code = new ArrayList<>();
    compileAssignment(node, debugAccessors, expr, scope, code);
    return ByteCodeUtils.compoundAppender(code);
  }

  /**
   * Called recursively to compile the tree of l-values we might have.
   */
  private static void compileAssignment(
      ASTNode node,
      AstAccessors debugAccessors,
      Expression leftValue,
      VariableScope scope,
      List<ByteCodeAppender> code)
      throws EvalException {
    if (leftValue instanceof Identifier) {
      code.add(compileAssignment(scope, (Identifier) leftValue));
    } else if (leftValue instanceof ListLiteral) {
      List<Expression> lValueExpressions = ((ListLiteral) leftValue).getElements();
      compileAssignment(node, debugAccessors, scope, lValueExpressions, code);
    } else {
      String message =
          String.format(
              "Can't assign to expression '%s', only to variables or nested tuples of variables",
              leftValue);
      throw new EvalExceptionWithStackTrace(new EvalException(node.getLocation(), message), node);
    }
  }

  /**
   * Assumes a collection of values on the top of the stack and assigns them to the l-value
   * expressions given.
   */
  private static void compileAssignment(
      ASTNode node,
      AstAccessors debugAccessors,
      VariableScope scope,
      List<Expression> lValueExpressions,
      List<ByteCodeAppender> code)
      throws EvalException {
    InternalVariable objects = scope.freshVariable(Collection.class);
    InternalVariable iterator = scope.freshVariable(Iterator.class);
    // convert the object on the stack into a collection and store it to a variable for loading
    // multiple times below below
    code.add(new ByteCodeAppender.Simple(debugAccessors.loadLocation, EvalUtils.toCollection));
    code.add(objects.store());
    append(
        code,
        // check that we got exactly the amount of objects in the collection that we need
        IntegerConstant.forValue(lValueExpressions.size()),
        objects.load(),
        debugAccessors.loadLocation, // TODO(bazel-team) load better location within tuple
        ByteCodeUtils.invoke(
            LValue.class, "checkSize", int.class, Collection.class, Location.class),
        // get an iterator to assign the objects
        objects.load(),
        ByteCodeUtils.invoke(Collection.class, "iterator"));
    code.add(iterator.store());
    // assign each object to the corresponding l-value
    for (Expression lValue : lValueExpressions) {
      code.add(
          new ByteCodeAppender.Simple(
              iterator.load(), ByteCodeUtils.invoke(Iterator.class, "next")));
      compileAssignment(node, debugAccessors, lValue, scope, code);
    }
  }

  /**
   * Compile assignment to a single identifier.
   */
  private static ByteCodeAppender compileAssignment(VariableScope scope, Identifier identifier) {
    // don't store to/create the _ "variable" the value is not needed, just remove it
    if (identifier.getName().equals("_")) {
      return new ByteCodeAppender.Simple(Removal.SINGLE);
    }
    return scope.getVariable(identifier).store();
  }

  /**
   * Checks that the size of a collection at runtime conforms to the amount of l-value expressions
   * we have to assign to.
   */
  public static void checkSize(int expected, Collection<?> collection, Location location)
      throws EvalException {
    int actual = collection.size();
    if (expected != actual) {
      throw new EvalException(
          location,
          String.format("lvalue has length %d, but rvalue has has length %d", expected, actual));
    }
  }
}
