package com.chenyang.druid.sql.visitor.functions;

import com.chenyang.druid.sql.ast.SQLExpr;
import com.chenyang.druid.sql.ast.expr.SQLIntegerExpr;
import com.chenyang.druid.sql.ast.expr.SQLMethodInvokeExpr;
import com.chenyang.druid.sql.visitor.SQLEvalVisitor;
import com.chenyang.druid.sql.visitor.SQLEvalVisitorUtils;
import java.util.List;

public class Greatest implements Function {
   public static final Greatest instance = new Greatest();

   public Object eval(SQLEvalVisitor visitor, SQLMethodInvokeExpr x) {
      Object result = null;

      for(SQLExpr item : x.getArguments()) {
         item.accept(visitor);
         Object itemValue = item.getAttributes().get("eval.value");
         if (result == null) {
            result = itemValue;
         } else if (SQLEvalVisitorUtils.gt(itemValue, result)) {
            result = itemValue;
         }
      }

      return result;
   }

   public Object eval(SQLMethodInvokeExpr x) {
      List<SQLExpr> parameters = x.getArguments();
      if (parameters.size() > 0) {
         SQLExpr p0 = (SQLExpr)parameters.get(0);
         if (p0 instanceof SQLIntegerExpr && ((SQLIntegerExpr)p0).getNumber() instanceof Integer) {
            int val = ((SQLIntegerExpr)p0).getNumber().intValue();

            for(int i = 1; i < parameters.size(); ++i) {
               SQLExpr param = (SQLExpr)parameters.get(i);
               if (!(param instanceof SQLIntegerExpr) || !(((SQLIntegerExpr)param).getNumber() instanceof Integer)) {
                  return SQLEvalVisitor.EVAL_ERROR;
               }

               int paramVal = ((SQLIntegerExpr)param).getNumber().intValue();
               if (paramVal > val) {
                  val = paramVal;
               }
            }

            return val;
         }
      }

      return SQLEvalVisitor.EVAL_ERROR;
   }
}
