package ru.yandex.webmaster3.storage.nca;

import java.util.stream.Stream;

import lombok.Value;
import org.springframework.stereotype.Repository;

import ru.yandex.webmaster3.storage.nca.data.CertificateIdByDomainEntry;
import ru.yandex.webmaster3.storage.nca.data.LogEntryType;
import ru.yandex.webmaster3.storage.util.clickhouse2.SimpleByteArrayOutputStream;
import ru.yandex.webmaster3.storage.util.clickhouse2.query.QueryBuilder;
import ru.yandex.webmaster3.storage.util.clickhouse2.query.Statement;

@Repository
public class CertificatesByIdCHDao extends AbstractCtlogCertificatesCHDao<CertificatesByIdCHDao.Row> {
    private static final String DB_NAME = DB_WEBMASTER3;
    private static final String SHARD_TABLE = "certificate_by_id";

    public Statement getCertificatesById(Statement certificateIds) {
        return QueryBuilder.selectDistinct(F.CERTIFICATE, F.TYPE)
                .from(DB_NAME, SHARD_TABLE)
                .where(QueryBuilder.inSubquery(certificateIds, F.SERIES_NUMBER, F.NOT_BEFORE, F.TYPE));
    }

    @Override
    protected SimpleByteArrayOutputStream packRow(SimpleByteArrayOutputStream bs, Row row) {
        return packRowValues(bs,
                row.getSerialNumber(),
                row.getNotBefore(),
                row.getCertificate(),
                row.getType().value()
        );
    }

    @Override
    // всегда один так как эта таблица не шардируется
    protected int getShard(Row row) {
        return 0;
    }

    @Override
    protected Stream<Row> rowFromEntry(CertificateIdByDomainEntry entry) {
        return Stream.of(
                new Row(
                        entry.getSerialNumber(),
                        entry.getNotBefore(),
                        entry.getCertificate(),
                        entry.getLogEntryType())
        );
    }

    @Override
    public String getDbName() {
        return DB_NAME;
    }

    @Override
    public String getTableName() {
        return SHARD_TABLE;
    }

    @Override
    public String[] getInsertFields() {
        return INSERT_FIELDS;
    }

    @Value
    public static class Row {

        String serialNumber;
        long notBefore;
        byte[] certificate;
        LogEntryType type;
    }

    private static final String[] INSERT_FIELDS = {F.SERIES_NUMBER, F.NOT_BEFORE,
            F.CERTIFICATE, F.TYPE};
}
