package link.at17.mid.tushare.data.typehandler;

import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import org.apache.ibatis.type.MappedJdbcTypes;
import org.apache.ibatis.type.MappedTypes;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;

import lombok.extern.slf4j.Slf4j;

import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;

@MappedTypes(List.class)
@MappedJdbcTypes(JdbcType.VARCHAR)
@Slf4j
public class JsonListTypeHandler extends BaseTypeHandler<List<?>> {
    private static final ObjectMapper mapper = new ObjectMapper();

    @Override
    public void setNonNullParameter(PreparedStatement ps, int i, List<?> parameter, JdbcType jdbcType) throws SQLException {
        try {
            ps.setString(i, mapper.writeValueAsString(parameter));
        } catch (JsonProcessingException | SQLException e) {
            log.error("将 {} 转换成 JSON String 并存储时错误", parameter, e);
        }
    }

    @Override
    public List<?> getNullableResult(ResultSet rs, String columnName) throws SQLException {
        String json = rs.getString(columnName);
        try {
            return mapper.readValue(json, new TypeReference<List<?>>() {});
        } catch (JsonProcessingException e) {
            log.error("将 JSON String {} 转换成 List<?> 时错误", json, e);
            return new ArrayList<>();
        }
    }

    @Override
    public List<?> getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
        try {
            return mapper.readValue(rs.getString(columnIndex), new TypeReference<List<?>>() {});
        } catch (JsonProcessingException | SQLException e) {
            log.error("将 ResultSet {} 转换成 List<?> 时错误", rs, e);
            return new ArrayList<>();
        }
    }

    @Override
    public List<?> getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
        try {
            return mapper.readValue(cs.getString(columnIndex), new TypeReference<List<?>>() {});
        } catch (JsonProcessingException | SQLException e) {
            log.error("将 CallableStatement {} 转换成 List<?> 时错误", cs, e);
            return new ArrayList<>();
        }
    }
}
