package com.persagy.dmp.typehandler;

import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.persagy.dmp.basic.dto.RelationCalDTO;
import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;
import org.apache.ibatis.type.MappedJdbcTypes;
import org.apache.ibatis.type.MappedTypes;
import org.springframework.util.Assert;

import java.io.IOException;
import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.*;

/***
 * Description: 处理关系计算子类对象
 * @author : lijie
 * @date :2021/11/23 18:18
 * Update By lijie 2021/11/23 18:18
 */
@MappedJdbcTypes({JdbcType.VARCHAR, JdbcType.OTHER})
@MappedTypes(Collection.class)
public class RelationCalTypeHandler extends BaseTypeHandler<List<RelationCalDTO>> {

    /**
     * ObjectMapper
     */
    private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();

    @Override
    public void setNonNullParameter(PreparedStatement ps, int i, List<RelationCalDTO> parameter, JdbcType jdbcType)
            throws SQLException {
        ps.setString(i, JSONUtil.toJsonStr(parameter));
    }

    @Override
    public List<RelationCalDTO> getNullableResult(ResultSet rs, String columnName) throws SQLException {
        String value = rs.getString(columnName);
        return convertToEntityAttribute(value);
    }


    @Override
    public List<RelationCalDTO> getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
        return convertToEntityAttribute(rs.getString(columnIndex));
    }


    @Override
    public List<RelationCalDTO> getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
        String value = cs.getString(columnIndex);
        return convertToEntityAttribute(value);
    }


    public List<RelationCalDTO> convertToEntityAttribute(String dbData) {
        if (StrUtil.isEmpty(dbData)) {
           return Collections.emptyList();
        }
        return toObject(dbData, new TypeReference<List<RelationCalDTO>>(){});
    }


    public static <T> T toObject(String json, TypeReference<List<RelationCalDTO>> javaType) {
        Assert.hasText(json, "[Assertion failed] - this json must have text; it must not be null, empty, or blank");
        Assert.notNull(javaType, "[Assertion failed] - javaType is required; it must not be null");
        try {
            return OBJECT_MAPPER.readValue(json, javaType);
        } catch (com.fasterxml.jackson.core.JsonParseException e) {
            throw new RuntimeException(e.getMessage(), e);
        } catch (JsonMappingException e) {
            throw new RuntimeException(e.getMessage(), e);
        } catch (IOException e) {
            throw new RuntimeException(e.getMessage(), e);
        }
    }
}
