package cn.axzo.msg.center.message.service.todo.queryanalyze;

import com.alibaba.druid.sql.ast.SQLObject;
import com.alibaba.druid.sql.ast.expr.SQLCharExpr;
import com.alibaba.druid.sql.ast.expr.SQLDoubleExpr;
import com.alibaba.druid.sql.ast.expr.SQLFloatExpr;
import com.alibaba.druid.sql.ast.expr.SQLIntegerExpr;
import com.alibaba.druid.sql.ast.expr.SQLNumberExpr;
import com.alibaba.druid.sql.ast.expr.SQLSmallIntExpr;
import com.alibaba.druid.sql.visitor.SQLASTVisitor;

import javax.annotation.Nullable;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * @author yanglin
 */
class EvalTypeVisitor implements SQLASTVisitor {

    private static final String TYPE = "type";
    private static final SimpleDateFormat SDF = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SS");
    static final EvalTypeVisitor INSTANCE = new EvalTypeVisitor();

    private EvalTypeVisitor() {}

    @Override
    public void endVisit(SQLNumberExpr x) {
        x.getParent().putAttribute(TYPE, x.getValue().getClass());
    }

    @Override
    public void endVisit(SQLSmallIntExpr x) {
        x.getParent().putAttribute(TYPE, x.getValue().getClass());
    }

    @Override
    public void endVisit(SQLIntegerExpr x) {
        x.getParent().putAttribute(TYPE, x.getValue().getClass());
    }

    @Override
    public void endVisit(SQLDoubleExpr x) {
        x.getParent().putAttribute(TYPE, Double.class);
    }

    @Override
    public void endVisit(SQLFloatExpr x) {
        x.getParent().putAttribute(TYPE, Float.class);
    }

    @Override
    public void endVisit(SQLCharExpr x) {
        Date date = asDate(x);
        x.getParent().putAttribute(TYPE, date == null ? String.class : Date.class);
    }

    @Nullable
    static Date asDate(SQLCharExpr x) {
        try {
            return SDF.parse((String) x.getValue());
        } catch (ParseException e) {
            return null;
        }
    }

    static Class<?> getType(SQLObject x) {
        return (Class<?>)x.getAttribute(TYPE);
    }
}