/*
 * Copyright 2008 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.jjs.impl.gflow.constants;

import com.google.gwt.dev.jjs.ast.Context;
import com.google.gwt.dev.jjs.ast.JBinaryOperation;
import com.google.gwt.dev.jjs.ast.JBinaryOperator;
import com.google.gwt.dev.jjs.ast.JBooleanLiteral;
import com.google.gwt.dev.jjs.ast.JExpression;
import com.google.gwt.dev.jjs.ast.JIntLiteral;
import com.google.gwt.dev.jjs.ast.JNullLiteral;
import com.google.gwt.dev.jjs.ast.JPrimitiveType;
import com.google.gwt.dev.jjs.ast.JValueLiteral;
import com.google.gwt.dev.jjs.ast.JVariableRef;
import com.google.gwt.dev.jjs.ast.JVisitor;
import com.google.gwt.dev.jjs.ast.js.JMultiExpression;
import com.google.gwt.dev.util.Preconditions;

/**
 * Evaluate expression based on current assumptions.
 */
public class ExpressionEvaluator {
  /**
   * Main evaluation visitor. 
   */
  private static class EvaluatorVisitor extends JVisitor {
    private final ConstantsAssumption assumptions;
    /**
     * Contains evaluation result for visited node. Is <code>null</code>
     * if we can't evaluate.
     */
    private JValueLiteral result = null;

    public EvaluatorVisitor(ConstantsAssumption assumptions) {
      this.assumptions = assumptions;
    }
    
    public JValueLiteral evaluate(JExpression expression) {
      Preconditions.checkNotNull(expression);
      accept(expression);
      return result;
    }
    
    @Override
    public boolean visit(JBinaryOperation x, Context ctx) {
      accept(x.getRhs());
      if (result == null) {
        return false;
      }
      JValueLiteral rhs = result;
      accept(x.getLhs());
      if (result == null) {
        return false;
      }
      JValueLiteral lhs = result;
      result = evalBinOp(x, lhs, rhs);
      return false;
    }

    @Override
    public boolean visit(JExpression x, Context ctx) {
      // We don't know what's this expression about. Can't evaluate it.
      result = null;
      return false;
    }

    @Override
    public boolean visit(JMultiExpression x, Context ctx) {
      accept(x.exprs.get(x.exprs.size() - 1));
      return false;
    }

    @Override
    public boolean visit(JValueLiteral x, Context ctx) {
      result = x;
      return false;
    }

    @Override
    public boolean visit(JVariableRef x, Context ctx) {
      result = assumptions != null ? assumptions.get(x.getTarget()) : null;
      return false;
    }
  }
  
  public static JValueLiteral evalBinOp(JBinaryOperation x, JValueLiteral lhs, 
      JValueLiteral rhs) {
    if (lhs instanceof JNullLiteral ||
        rhs instanceof JNullLiteral) {
      if (x.getOp() == JBinaryOperator.EQ) {
        return JBooleanLiteral.get(
            (lhs instanceof JNullLiteral) && (rhs instanceof JNullLiteral));
      } else if (x.getOp() == JBinaryOperator.NEQ) {
        return JBooleanLiteral.get(
            !(lhs instanceof JNullLiteral) || !(rhs instanceof JNullLiteral));
      }
    }
    
    if (!lhs.getType().equals(rhs.getType())) {
      // do not even try to get type conversions right :)
      return null;
    }
    
    // TODO: support other types.
    
    if (lhs.getType().equals(JPrimitiveType.INT)) {
      if (!(lhs instanceof JIntLiteral) ||
          !(rhs instanceof JIntLiteral)) {
        return null;
      }
      
      int a = ((JIntLiteral) lhs).getValue();
      int b = ((JIntLiteral) rhs).getValue();
      
      switch (x.getOp()) {
        case ADD:
          return new JIntLiteral(x.getSourceInfo(), a + b); 
        case MUL:
          return new JIntLiteral(x.getSourceInfo(), a * b); 
        case SUB:
          return new JIntLiteral(x.getSourceInfo(), a - b); 
        case DIV:
          if (b != 0) { 
            return new JIntLiteral(x.getSourceInfo(), a / b);
          } else {
            return null;
          }
        case EQ:
          return JBooleanLiteral.get(a == b); 
        case NEQ:
          return JBooleanLiteral.get(a != b); 
        case GT:
          return JBooleanLiteral.get(a > b); 
        case GTE:
          return JBooleanLiteral.get(a >= b); 
        case LT:
          return JBooleanLiteral.get(a < b); 
        case LTE:
          return JBooleanLiteral.get(a <= b); 
          
        default:
          return null;
      }
    } else if (lhs.getType().equals(JPrimitiveType.BOOLEAN)) {
      if (!(lhs instanceof JBooleanLiteral) ||
          !(rhs instanceof JBooleanLiteral)) {
        return null;
      }
      
      boolean a = ((JBooleanLiteral) lhs).getValue();
      boolean b = ((JBooleanLiteral) rhs).getValue();
      
      switch (x.getOp()) {
        case EQ:
          return JBooleanLiteral.get(a == b); 
        case NEQ:
          return JBooleanLiteral.get(a != b); 
          
        default:
          return null;
      }
    }

    return null;
  }

  public static JValueLiteral evaluate(JExpression expression,
      ConstantsAssumption assumptions) {
    return new EvaluatorVisitor(assumptions).evaluate(expression);
  }
}
