package com.yuchen.saas.park.api.config.convert;

import com.yuchen.saas.park.api.commons.CodeAble;
import org.apache.ibatis.type.JdbcType;
import org.apache.ibatis.type.TypeHandler;

import java.lang.reflect.ParameterizedType;
import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Arrays;

abstract class EnumConverter<T extends Enum<T> & CodeAble> implements TypeHandler<T> {
    private final Class<T> clazz;

    @SuppressWarnings("unchecked")
    protected EnumConverter() {
        this.clazz = (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
    }

    @Override
    public void setParameter(PreparedStatement ps, int i, T parameter, JdbcType jdbcType) throws SQLException {
        ps.setInt(i, parameter.getCode());
    }

    @Override
    public T getResult(ResultSet rs, String columnName) throws SQLException {
        return this.getByInt(rs.getInt(columnName));
    }

    @Override
    public T getResult(ResultSet rs, int columnIndex) throws SQLException {
        return this.getByInt(rs.getInt(columnIndex));
    }

    @Override
    public T getResult(CallableStatement cs, int columnIndex) throws SQLException {
        return this.getByInt(cs.getInt(columnIndex));
    }

    public T getByInt(int i) {
        return Arrays.stream(clazz.getEnumConstants()).filter(o -> o.getCode() == i).findFirst().orElseThrow(IllegalAccessError::new);
    }
}
