package com.ruoyi.system.domain.md.util;

import com.ruoyi.system.domain.md.NewmsgInboxExample;
import com.ruoyi.system.domain.md.enums.OperatorType;
import org.apache.http.util.Asserts;

import java.lang.reflect.Constructor;

public class FormInboxExample4Json extends NewmsgInboxExample {

    public static final String json_field = "params";
    public static final String convert_format = "JSON_EXTRACT(%s,'$.%s')";

    public static String convertField(String fieldName){
        return String.format(convert_format,json_field,fieldName);
    }

    private static Criterion build(String condition,Object value){
        Constructor<Criterion> c = null;
        try {
            c = (Criterion.class).getDeclaredConstructor(String.class,Object.class);
            c.setAccessible(true);
            return c.newInstance(condition,value);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    public static void addCriterion(Criteria criteria,OperateParam param) {
        Asserts.notNull(param,"OperateParam");
        Asserts.notBlank(param.getFieldName(),"fieldName");
        Asserts.notBlank(param.getOperate(),"operate");

        OperatorType type = OperatorType.getByCode(param.getOperate().toLowerCase());
        if(type == null){
            throw new RuntimeException("no match OperatorType for code :" + param.getOperate());
        }
        String field4Json = convertField(param.getFieldName());
        if(OperatorType.like.equals(type)){
            param.setFieldValue("%"+param.getFieldValue()+"%");
        }

        Criterion criterion = build(type.execute(field4Json), param.getFieldValue());
        if(criterion != null){
            criteria.getAllCriteria().add(criterion);
        }
    }

    /**
     * @author vidar
     * date 2024/6/6
     * description
     **/
    public static class OperateParam {
        private String fieldName;
        private String operate;
        private Object fieldValue;

        public OperateParam() {}

        public OperateParam(String fieldName, String operate, Object fieldValue) {
            this.fieldName = fieldName;
            this.operate = operate;
            this.fieldValue = fieldValue;
        }

        public String getFieldName() {
            return this.fieldName;
        }

        public void setFieldName(String fieldName) {
            this.fieldName = fieldName;
        }

        public Object getFieldValue() {
            return this.fieldValue;
        }

        public void setFieldValue(Object fieldValue) {
            this.fieldValue = fieldValue;
        }

        public String getOperate() {
            return this.operate;
        }

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