package meerkat.bulletinboard.sqlserver.mappers;

import com.google.protobuf.InvalidProtocolBufferException;
import meerkat.bulletinboard.sqlserver.BulletinBoardSQLServer.*;
import meerkat.bulletinboard.sqlserver.BulletinBoardSQLServer.SQLQueryProvider.*;
import meerkat.comm.MessageOutputStream;
import meerkat.protobuf.BulletinBoardApi.*;
import meerkat.protobuf.Crypto;
import org.springframework.jdbc.core.RowCallbackHandler;
import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;

import java.io.IOException;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;

/**
 * Created by Arbel Deutsch Peled on 21-Feb-16.
 */
public class MessageCallbackHandler implements RowCallbackHandler {

    private final NamedParameterJdbcTemplate jdbcTemplate;
    private final SQLQueryProvider sqlQueryProvider;
    private final MessageOutputStream<BulletinBoardMessage> out;

    public MessageCallbackHandler(NamedParameterJdbcTemplate jdbcTemplate, SQLQueryProvider sqlQueryProvider, MessageOutputStream<BulletinBoardMessage> out) {

        this.jdbcTemplate = jdbcTemplate;
        this.sqlQueryProvider = sqlQueryProvider;
        this.out = out;

    }

    @Override
    public void processRow(ResultSet rs) throws SQLException {

        BulletinBoardMessage.Builder result;

        try {

            result = BulletinBoardMessage.newBuilder()
                    .setEntryNum(rs.getLong(1))
                    .setMsg(UnsignedBulletinBoardMessage.parseFrom(rs.getBytes(2)));


        } catch (InvalidProtocolBufferException e) {
            //TODO: log
            return;
        }

        // Retrieve signatures

        MapSqlParameterSource sqlParameterSource = new MapSqlParameterSource();
        sqlParameterSource.addValue(QueryType.GET_SIGNATURES.getParamName(0), result.getEntryNum());

        List<Crypto.Signature> signatures = jdbcTemplate.query(
                sqlQueryProvider.getSQLString(QueryType.GET_SIGNATURES),
                sqlParameterSource,
                new SignatureMapper());

        // Append signatures
        result.addAllSig(signatures);

        // Finalize message and add to message list.

        try {

            out.writeMessage(result.build());

        } catch (IOException e) {

            //TODO: log
            e.printStackTrace();

        }

    }

}
