/*
 * Copyright 2012 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.dev.js.ast.JsArrayAccess;
import com.google.gwt.dev.js.ast.JsBinaryOperation;
import com.google.gwt.dev.js.ast.JsContext;
import com.google.gwt.dev.js.ast.JsExpression;
import com.google.gwt.dev.js.ast.JsFor;
import com.google.gwt.dev.js.ast.JsInvocation;
import com.google.gwt.dev.js.ast.JsModVisitor;
import com.google.gwt.dev.js.ast.JsNameRef;
import com.google.gwt.dev.js.ast.JsNew;
import com.google.gwt.dev.js.ast.JsNode;
import com.google.gwt.dev.js.ast.JsPostfixOperation;
import com.google.gwt.dev.js.ast.JsPrefixOperation;
import com.google.gwt.dev.js.ast.JsPropertyInitializer;
import com.google.gwt.dev.js.ast.JsUnaryOperator;
import com.google.gwt.dev.js.ast.JsWhile;
import com.google.gwt.thirdparty.guava.common.collect.Sets;

import java.util.Set;

/**
 * A visitor that visits every location in the AST where instrumentation is
 * desirable.
 */
public abstract class CoverageVisitor extends JsModVisitor {
  private int lastLine = -1;
  private String lastFile = "";
  private Set<String> instrumentedFiles;

  /**
   * Nodes in this set are used in a context that expects a reference, not
   * just an arbitrary expression. For example, <code>delete</code> takes a
   * reference. These are tracked because it wouldn't be safe to rewrite
   * <code>delete foo.bar</code> to <code>delete (line='123',foo).bar</code>.
   */
  private final Set<JsNode> nodesInRefContext = Sets.newHashSet();

  public CoverageVisitor(Set<String> instrumentedFiles) {
    this.instrumentedFiles = instrumentedFiles;
  }

  @Override public void endVisit(JsArrayAccess x, JsContext ctx) {
    visitExpression(x, ctx);
  }

  @Override public void endVisit(JsBinaryOperation x, JsContext ctx) {
    visitExpression(x, ctx);
  }

  @Override public void endVisit(JsInvocation x, JsContext ctx) {
    nodesInRefContext.remove(x.getQualifier());
    visitExpression(x, ctx);
  }

  @Override public void endVisit(JsNameRef x, JsContext ctx) {
    visitExpression(x, ctx);
  }

  @Override public void endVisit(JsNew x, JsContext ctx) {
    visitExpression(x, ctx);
  }

  @Override public void endVisit(JsPostfixOperation x, JsContext ctx) {
    visitExpression(x, ctx);
  }

  @Override public void endVisit(JsPrefixOperation x, JsContext ctx) {
    visitExpression(x, ctx);
    nodesInRefContext.remove(x.getArg());
  }

  /**
   * This is essentially a hacked-up version of JsFor.traverse to account for
   * flow control differing from visitation order. It resets lastFile and
   * lastLine before the condition and increment expressions in the for loop
   * so that location data will be recorded correctly.
   */
  @Override public boolean visit(JsFor x, JsContext ctx) {
    if (x.getInitExpr() != null) {
      x.setInitExpr(accept(x.getInitExpr()));
    } else if (x.getInitVars() != null) {
      x.setInitVars(accept(x.getInitVars()));
    }

    if (x.getCondition() != null) {
      resetPosition();
      x.setCondition(accept(x.getCondition()));
    }

    if (x.getIncrExpr() != null) {
      resetPosition();
      x.setIncrExpr(accept(x.getIncrExpr()));
    }
    accept(x.getBody());
    return false;
  }

  @Override public boolean visit(JsInvocation x, JsContext ctx) {
    nodesInRefContext.add(x.getQualifier());
    return true;
  }

  @Override public boolean visit(JsPropertyInitializer x, JsContext ctx) {
    // Do not instrument labels.
    x.setValueExpr(accept(x.getValueExpr()));
    return false;
  }

  @Override public boolean visit(JsPrefixOperation x, JsContext ctx) {
    if (x.getOperator() == JsUnaryOperator.DELETE
        || x.getOperator() == JsUnaryOperator.TYPEOF) {
      nodesInRefContext.add(x.getArg());
    }
    return true;
  }

  /**
   * Similar to JsFor, this resets the current location information before
   * evaluating the condition.
   */
  @Override public boolean visit(JsWhile x, JsContext ctx) {
    resetPosition();
    x.setCondition(accept(x.getCondition()));
    accept(x.getBody());
    return false;
  }

  protected abstract void endVisit(JsExpression x, JsContext ctx);

  private void resetPosition() {
    lastFile = "";
    lastLine = -1;
  }

  private void visitExpression(JsExpression x, JsContext ctx) {
    if (ctx.isLvalue()) {
      // Assignments to comma expressions aren't legal
      return;
    } else if (nodesInRefContext.contains(x)) {
      // Don't modify references into non-references
      return;
    } else if (!instrumentedFiles.contains(x.getSourceInfo().getFileName())) {
      return;
    } else if (x.getSourceInfo().getStartLine() == lastLine
        && (x.getSourceInfo().getFileName().equals(lastFile))) {
      return;
    }
    lastLine = x.getSourceInfo().getStartLine();
    lastFile = x.getSourceInfo().getFileName();
    endVisit(x, ctx);
  }
}
