/*
 * Copyright 2018 Scytl Secure Electronic Voting SA
 *
 * All rights reserved
 *
 * See our extended copyright notice in *file 'Copyright.txt' which is part of this source code package
 */
package com.scytl.products.ov.channel.cc.orchestrator.mixdec.infrastructure.persistence;

import java.util.List;

import javax.ejb.Stateless;
import javax.persistence.TypedQuery;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.scytl.cryptolib.api.exceptions.CryptoLibException;
import com.scytl.products.ov.channel.cc.orchestrator.mixdec.domain.model.MixDecNodeOutput;
import com.scytl.products.ov.channel.cc.orchestrator.mixdec.domain.model.MixDecNodeOutputId;
import com.scytl.products.ov.commons.beans.exceptions.DuplicateEntryException;
import com.scytl.products.ov.commons.dto.MixingDTO;
import com.scytl.products.ov.commons.dto.mixing.MixingPayload;
import com.scytl.products.ov.commons.infrastructure.persistence.BaseRepositoryImpl;
import com.scytl.products.ov.commons.ui.ws.rs.ObjectMappers;

/**
 * Implementation of the mix-dec node output repository based on BaseRepositoryImpl.
 */
@Stateless
public class MixDecNodeOutputRepositoryImpl
        extends BaseRepositoryImpl<MixDecNodeOutput, MixDecNodeOutputId>
        implements MixDecNodeOutputRepository {
   
	private static final Logger LOG = LoggerFactory.getLogger("std");

    private static final String PARAMETER_TENANT_ID = "tenantId";

    private static final String PARAMETER_ELECTION_EVENT_ID = "electionEventId";

    private static final String PARAMETER_BALLOT_BOX_ID = "ballotBoxId";

    @Override
    public MixDecNodeOutput save(MixingDTO mixingDTO) throws DuplicateEntryException {
        // Create a partial results object from the mixing DTO and store it.
        MixDecNodeOutputId id = new MixDecNodeOutputId(mixingDTO.getPayload().getVoteSetId(),
                mixingDTO.getLastNodeName());

        MixingPayload payload = mixingDTO.getPayload();
        try {
            // Serialise the payload to JSON.
            String payloadJson = ObjectMappers.toJson(payload);

            LOG.debug("Storing node output ({} bytes)...", payloadJson.length());
            return save(new MixDecNodeOutput(id, payloadJson));
        } catch (JsonProcessingException e) {
            throw new CryptoLibException("Error serializing the mixing payload", e);
        }
    }

    @Override
    public List<MixDecNodeOutput> findForAllNodes(String tenantId, String electionEventId, String ballotBoxId) {
        final TypedQuery<MixDecNodeOutput> query = entityManager
            .createQuery("SELECT o FROM MixDecNodeOutput o " + " WHERE o.id.tenantId = :tenantId "
                + " AND o.id.electionEventId = :electionEventId "
                + " AND o.id.ballotBoxId = :ballotBoxId", MixDecNodeOutput.class);
        query.setParameter(PARAMETER_TENANT_ID, tenantId);
        query.setParameter(PARAMETER_ELECTION_EVENT_ID, electionEventId);
        query.setParameter(PARAMETER_BALLOT_BOX_ID, ballotBoxId);

        return query.getResultList();
    }
}
