package com.liangjian.dataplatform.member.util.dynamic;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.Path;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import java.util.Date;

/**
 * Created by huangziqi on 2019/12/17
 */
public class DynamicFilter {
    protected String field;
    protected OperateType operate;
    protected String value;

    public <A> A transportType(Class<A> clazz) {
        if(clazz.equals(Integer.class)) {
            return (A) Integer.valueOf(value);
        } else if(clazz.equals(Long.class)) {
            return (A) Long.valueOf(value);
        } else if(clazz.equals(Double.class)) {
            return (A) Double.valueOf(value);
        } else if(clazz.equals(Float.class)) {
            return (A) Float.valueOf(value);
        } else if(clazz.equals(Date.class)) {
            return (A) new Date(value);
        } else if(clazz.equals(Boolean.class)) {
            return (A) Boolean.valueOf(value);
        } else if(clazz.equals(String.class)) {
            return (A) value;
        } else {
            throw new RuntimeException("unknown filter type");
        }
    }

    public <A> Predicate toJpaSpecification(Root<A> root, CriteriaBuilder criteriaBuilder) {
        switch (operate) {
            case Equal: {
                Path path = root.get(field);
                return criteriaBuilder.equal(path, transportType(path.getJavaType()));
            }
            case NotEqual:{
                Path path = root.get(field);
                return criteriaBuilder.notEqual(path, transportType(path.getJavaType()));
            }
            case Less: return criteriaBuilder.lt(root.get(field).as(Double.class), Double.valueOf(value));
            case LessEqual: return criteriaBuilder.lt(root.get(field).as(Double.class), Double.valueOf(value));
            case Greater: return criteriaBuilder.gt(root.get(field).as(Double.class), Double.valueOf(value));
            case GreaterEqual: return criteriaBuilder.gt(root.get(field).as(Double.class), Double.valueOf(value));
            case Contains: return criteriaBuilder.like(root.get(field), "%"+value+"%");
            case StartWith: return criteriaBuilder.like(root.get(field), value+"%");
            case EndWith: return criteriaBuilder.like(root.get(field), "%"+value);
            default: throw new RuntimeException("未知对应判断操作符");
        }
    }

    public String getField() {
        return field;
    }

    public void setField(String field) {
        this.field = field;
    }

    public OperateType getOperate() {
        return operate;
    }

    public void setOperate(OperateType operate) {
        this.operate = operate;
    }

    public String getValue() {
        return value;
    }

    public void setValue(String value) {
        this.value = value;
    }
}
