/*
 * 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.JBooleanLiteral;
import com.google.gwt.dev.jjs.ast.JDoubleLiteral;
import com.google.gwt.dev.jjs.ast.JExpression;
import com.google.gwt.dev.jjs.ast.JFloatLiteral;
import com.google.gwt.dev.jjs.ast.JLocalRef;
import com.google.gwt.dev.jjs.ast.JParameterRef;
import com.google.gwt.dev.jjs.ast.JValueLiteral;
import com.google.gwt.dev.jjs.ast.JVisitor;
import com.google.gwt.dev.jjs.ast.js.JMultiExpression;

/**
 * Assumption deducer analyzes the expression, knowing its value, and deduces
 * variables constant values assumptions from it.
 */
final class AssumptionDeducer extends JVisitor {
  /**
   * Deduce assumptions, knowing that <code>expression</code> evaluates to
   * <code>value</code> and stores individual variable assumptions in the 
   * <code>assumption</code> parameter. It will never override any existing
   * constant assumptions. It will override top and bottom assumptions though.
   */
  static void deduceAssumption(
      JExpression expression, final JValueLiteral value, 
      final ConstantsAssumption.Updater assumption) {
    new AssumptionDeducer(value, assumption).accept(expression);
  }
  private final ConstantsAssumption.Updater assumption;
  
  /**
   * Contains the value of evaluating expression we're currently visiting.
   * Is <code>null</code> if we do not know current expression value.
   */
  private JValueLiteral currentValue;

  AssumptionDeducer(JValueLiteral value, ConstantsAssumption.Updater assumption) {
    this.assumption = assumption;
    currentValue = value;
  }

  @SuppressWarnings("incomplete-switch")
  @Override
  public boolean visit(JBinaryOperation x, Context ctx) {
    switch (x.getOp()) {
      case EQ:
        if (isTrue(currentValue)) {
          if (x.getRhs() instanceof JValueLiteral &&
              isSubstitutableIfEquals(x.getRhs())) {
            currentValue = (JValueLiteral) x.getRhs();
            accept(x.getLhs());
            return false;
          } else if (x.getLhs() instanceof JValueLiteral &&
              isSubstitutableIfEquals(x.getLhs())) {
            currentValue = (JValueLiteral) x.getLhs();
            accept(x.getRhs());
            return false;
          }
        } 
        break;
        
      case NEQ:
        if (isFalse(currentValue)) {
          if (x.getRhs() instanceof JValueLiteral &&
              isSubstitutableIfEquals(x.getRhs())) {
            currentValue = (JValueLiteral) x.getRhs();
            accept(x.getLhs());
            return false;
          } else if (x.getLhs() instanceof JValueLiteral &&
              isSubstitutableIfEquals(x.getLhs())) {
            currentValue = (JValueLiteral) x.getLhs();
            accept(x.getRhs());
            return false;
          }
        } 
        break;
        
      case AND:
        if (isTrue(currentValue)) {
          accept(x.getLhs());
          currentValue = JBooleanLiteral.get(true);
          accept(x.getRhs());
          return false;
        }
        break;

      case OR:
        if (isFalse(currentValue)) {
          accept(x.getLhs());
          currentValue = JBooleanLiteral.FALSE;
          accept(x.getRhs());
          return false;
        }
        break;
    }
    currentValue = null;
    return true;
  }

  @Override
  public boolean visit(JExpression x, Context ctx) {
    // Unknown expression. Do not go inside.
    return false;
  }

  @Override
  public boolean visit(JLocalRef x, Context ctx) {
    if (assumption.hasAssumption(x.getTarget())) {
      // Expression evaluation can't change existing assumptions
      return false;
    }
    assumption.set(x.getTarget(), currentValue);
    return false;
  }

  @Override
  public boolean visit(JMultiExpression x, Context ctx) {
    // Knowing the value multi expression, we know the value of its last 
    // expression only.
    accept(x.exprs.get(x.exprs.size() - 1));
    return false;
  }

  @Override
  public boolean visit(JParameterRef x, Context ctx) {
    if (assumption.hasAssumption(x.getTarget())) {
      // Expression evaluation shouldn't change existing assumptions
      return false;
    }
    assumption.set(x.getTarget(), currentValue);
    return false;
  }

  private boolean isFalse(JValueLiteral value) {
    return value instanceof JBooleanLiteral &&
        !((JBooleanLiteral) value).getValue();
  }

  /**
   * Checks that if some expression equals <code>e</code>, then we can freely
   * substitute it by e. 
   */
  private boolean isSubstitutableIfEquals(JExpression e) {
    if (!(e instanceof JValueLiteral)) {
      return false;
    }
    
    if (e instanceof JFloatLiteral && 
        ((JFloatLiteral) e).getValue() == 0.0f) {
      // There are +0.0 and -0.0. And both of them are equal.
      // We can't substitute 0.0 instead of them.
      return false;
    }
    
    if (e instanceof JDoubleLiteral && 
        ((JDoubleLiteral) e).getValue() == 0.0d) {
      // There are +0.0 and -0.0. And both of them are equal.
      // We can't substitute 0.0 instead of them.
      return false;
    }

    return true;
  }

  private boolean isTrue(JValueLiteral value) {
    return value instanceof JBooleanLiteral &&
        ((JBooleanLiteral) value).getValue();
  }
}