package org.checkerframework.dataflow.constantpropagation;

import java.util.List;
import org.checkerframework.checker.nullness.qual.Nullable;
import org.checkerframework.dataflow.analysis.ConditionalTransferResult;
import org.checkerframework.dataflow.analysis.ForwardTransferFunction;
import org.checkerframework.dataflow.analysis.RegularTransferResult;
import org.checkerframework.dataflow.analysis.TransferInput;
import org.checkerframework.dataflow.analysis.TransferResult;
import org.checkerframework.dataflow.cfg.UnderlyingAST;
import org.checkerframework.dataflow.cfg.node.AbstractNodeVisitor;
import org.checkerframework.dataflow.cfg.node.AssignmentNode;
import org.checkerframework.dataflow.cfg.node.EqualToNode;
import org.checkerframework.dataflow.cfg.node.IntegerLiteralNode;
import org.checkerframework.dataflow.cfg.node.LocalVariableNode;
import org.checkerframework.dataflow.cfg.node.Node;

public class ConstantPropagationTransfer
    extends AbstractNodeVisitor<
        TransferResult<Constant, ConstantPropagationStore>,
        TransferInput<Constant, ConstantPropagationStore>>
    implements ForwardTransferFunction<Constant, ConstantPropagationStore> {

  @Override
  public ConstantPropagationStore initialStore(
      UnderlyingAST underlyingAST, @Nullable List<LocalVariableNode> parameters) {
    ConstantPropagationStore store = new ConstantPropagationStore();
    return store;
  }

  @Override
  public TransferResult<Constant, ConstantPropagationStore> visitLocalVariable(
      LocalVariableNode node, TransferInput<Constant, ConstantPropagationStore> before) {
    ConstantPropagationStore store = before.getRegularStore();
    Constant value = store.getInformation(node);
    return new RegularTransferResult<>(value, store);
  }

  @Override
  public TransferResult<Constant, ConstantPropagationStore> visitNode(
      Node n, TransferInput<Constant, ConstantPropagationStore> p) {
    return new RegularTransferResult<>(null, p.getRegularStore());
  }

  @Override
  public TransferResult<Constant, ConstantPropagationStore> visitAssignment(
      AssignmentNode n, TransferInput<Constant, ConstantPropagationStore> pi) {
    ConstantPropagationStore p = pi.getRegularStore();
    Node target = n.getTarget();
    Constant info = null;
    if (target instanceof LocalVariableNode) {
      LocalVariableNode t = (LocalVariableNode) target;
      info = p.getInformation(n.getExpression());
      p.setInformation(t, info);
    }
    return new RegularTransferResult<>(info, p);
  }

  @Override
  public TransferResult<Constant, ConstantPropagationStore> visitIntegerLiteral(
      IntegerLiteralNode n, TransferInput<Constant, ConstantPropagationStore> pi) {
    ConstantPropagationStore p = pi.getRegularStore();
    Constant c = new Constant(n.getValue());
    p.setInformation(n, c);
    return new RegularTransferResult<>(c, p);
  }

  @Override
  public TransferResult<Constant, ConstantPropagationStore> visitEqualTo(
      EqualToNode n, TransferInput<Constant, ConstantPropagationStore> pi) {
    ConstantPropagationStore p = pi.getRegularStore();
    ConstantPropagationStore old = p.copy();
    Node left = n.getLeftOperand();
    Node right = n.getRightOperand();
    process(p, left, right);
    process(p, right, left);
    return new ConditionalTransferResult<>(null, p, old);
  }

  protected void process(ConstantPropagationStore p, Node a, Node b) {
    Constant val = p.getInformation(a);
    if (b instanceof LocalVariableNode && val.isConstant()) {
      p.setInformation(b, val);
    }
  }
}
