package cn.fateverse.query.submeter.result;

import cn.fateverse.query.submeter.executor.ForceExecuteTemplate;
import cn.fateverse.query.submeter.unsupported.AbstractUnsupportedOperationResultSet;
import lombok.Getter;
import org.apache.shardingsphere.sql.parser.binder.statement.SQLStatementContext;

import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.SQLWarning;
import java.util.List;

/**
 * @author Clay
 * @date 2024/4/7 16:59
 */
public abstract class AbstractResultSetAdapter extends AbstractUnsupportedOperationResultSet {

    @Getter
    private final List<ResultSet> resultSets;

    @Getter
    private final SQLStatementContext sqlStatementContext;

    private boolean closed;

    private final ForceExecuteTemplate<ResultSet> forceExecuteTemplate = new ForceExecuteTemplate<>();


    protected AbstractResultSetAdapter(List<ResultSet> resultSets, SQLStatementContext sqlStatementContext) {
        this.resultSets = resultSets;
        this.sqlStatementContext = sqlStatementContext;
    }

    @Override
    public final ResultSetMetaData getMetaData() throws SQLException {
        return new SubmeterResultSetMetaData(resultSets.get(0).getMetaData(), sqlStatementContext);
    }

    @Override
    public final int findColumn(final String columnLabel) throws SQLException {
        return resultSets.get(0).findColumn(columnLabel);
    }

    @Override
    public final void close() throws SQLException {
        closed = true;
        forceExecuteTemplate.execute(resultSets, ResultSet::close);
    }

    @Override
    public final boolean isClosed() {
        return closed;
    }

    @Override
    public final void setFetchDirection(final int direction) throws SQLException {
        forceExecuteTemplate.execute(resultSets, resultSet -> resultSet.setFetchDirection(direction));
    }

    @Override
    public final int getFetchDirection() throws SQLException {
        return resultSets.get(0).getFetchDirection();
    }

    @Override
    public final void setFetchSize(final int rows) throws SQLException {
        forceExecuteTemplate.execute(resultSets, resultSet -> resultSet.setFetchSize(rows));
    }

    @Override
    public final int getFetchSize() throws SQLException {
        return resultSets.get(0).getFetchSize();
    }

    @Override
    public final int getType() throws SQLException {
        return resultSets.get(0).getType();
    }

    @Override
    public final int getConcurrency() throws SQLException {
        return resultSets.get(0).getConcurrency();
    }

    @Override
    public final SQLWarning getWarnings() throws SQLException {
        return resultSets.get(0).getWarnings();
    }

    @Override
    public final void clearWarnings() throws SQLException {
        forceExecuteTemplate.execute(resultSets, ResultSet::clearWarnings);
    }


}
