/*
 * Copyright 2010 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.js;

import com.google.gwt.core.ext.BadPropertyValueException;
import com.google.gwt.core.ext.PropertyOracle;
import com.google.gwt.core.ext.SelectionProperty;
import com.google.gwt.core.ext.TreeLogger;
import com.google.gwt.dev.jjs.SourceInfo;
import com.google.gwt.dev.js.ast.JsBinaryOperation;
import com.google.gwt.dev.js.ast.JsBinaryOperator;
import com.google.gwt.dev.js.ast.JsContext;
import com.google.gwt.dev.js.ast.JsExpression;
import com.google.gwt.dev.js.ast.JsModVisitor;
import com.google.gwt.dev.js.ast.JsPrefixOperation;
import com.google.gwt.dev.js.ast.JsProgram;
import com.google.gwt.dev.js.ast.JsUnaryOperator;

/**
 * Coerces lhs of right shift operations to int. Necessary for Safari 5 bug
 * https://bugs.webkit.org/show_bug.cgi?id=40367 fixed in
 * http://trac.webkit.org/changeset/60990 -- this should be removed once that
 * fix has been pushed.
 */
public class JsCoerceIntShift {
  // TODO(jat): remove this once Safari 5 has the update

  /**
   * Rewrite a >> b as (~~a) >> b.
   */
  private static class MyVisitor extends JsModVisitor {

    @Override
    public void endVisit(JsBinaryOperation x, JsContext ctx) {
      JsBinaryOperator op = x.getOperator();
      if (op != JsBinaryOperator.SHR && op != JsBinaryOperator.SHRU) {
        return;
      }

      SourceInfo sourceInfo = x.getSourceInfo();
      JsExpression lhs = x.getArg1();
      JsExpression rhs = x.getArg2();
      JsExpression newNode = new JsBinaryOperation(sourceInfo, op,
          new JsPrefixOperation(sourceInfo, JsUnaryOperator.BIT_NOT,
              new JsPrefixOperation(sourceInfo, JsUnaryOperator.BIT_NOT, lhs)),
          rhs);
      ctx.replaceMe(newNode);
    }
  }

  /**
   * If this permutation may be executed on WebKit, rewrite a >> b as ~~a >> b.
   * 
   * @param program
   * @param logger
   * @param propertyOracles
   * @return true if any changes were made
   */
  public static boolean exec(JsProgram program, TreeLogger logger,
      PropertyOracle[] propertyOracles) {
    boolean seenWebKit = false;
    for (PropertyOracle oracle : propertyOracles) {
      try {
        SelectionProperty prop = oracle.getSelectionProperty(logger,
            "user.agent");
        // TODO(jat): more checks if we split up the safari permutation
        if ("safari".equals(prop.getCurrentValue())) {
          seenWebKit = true;
          break;
        }
      } catch (BadPropertyValueException e) {
        // if we couldn't get the property, assume this might be used on WebKit.
        seenWebKit = true;
        break;
      }
    }
    if (!seenWebKit) {
      return false;
    }
    MyVisitor v = new MyVisitor();
    v.accept(program);
    return v.didChange();
  }
}
