/*
 * 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.domain.infrastructure.persistence;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.mockito.Matchers.anyString;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.when;

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.channel.cc.orchestrator.mixdec.infrastructure.persistence.MixDecNodeOutputRepositoryImpl;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import javax.persistence.EntityManager;
import javax.persistence.TypedQuery;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.mockito.runners.MockitoJUnitRunner;

@RunWith(MockitoJUnitRunner.class)
public class MixDecNodeOutputRepositoryImplTest {

    private static final String TENANT_ID = "100";

    private static final String EE_ID = "2903294";

    private static final String BB_ID = "3902904";

    private static final Set<String> NODE_NAMES =
            Stream.of("1", "2", "3").collect(Collectors.toSet());

    private static final int VOTE_SET_INDEX = 0;

    @InjectMocks
    private MixDecNodeOutputRepositoryImpl sut = new MixDecNodeOutputRepositoryImpl();

    @Mock
    private EntityManager entityManagerMock;

    @Mock
    private TypedQuery<MixDecNodeOutput> mockQuery;

    @Before
    public void init() {
        MockitoAnnotations.initMocks(getClass());
    }

    @Test
    public void testFindForAllNodes() {
        // Serialise to JSON where needed.
        String payloadJson = "{payload:true}";

        List<MixDecNodeOutput> nodeOutputs = NODE_NAMES.stream()
                .map(nodeName -> new MixDecNodeOutput(
                        new MixDecNodeOutputId(TENANT_ID, EE_ID, BB_ID, VOTE_SET_INDEX, nodeName),
                        payloadJson)).collect(Collectors.toList());

        when(entityManagerMock.createQuery(anyString(), eq(MixDecNodeOutput.class)))
                .thenReturn(mockQuery);
        when(mockQuery.getResultList()).thenReturn(nodeOutputs);

        List<MixDecNodeOutput> retrievedNodeOutputs = sut.findForAllNodes(TENANT_ID, EE_ID, BB_ID);

        assertEquals(retrievedNodeOutputs.size(), NODE_NAMES.size());

        MixDecNodeOutput oneOutput = retrievedNodeOutputs.iterator().next();
        assertTrue(NODE_NAMES.contains(oneOutput.getNodeName()));
        // Cheekily help with MixDecNodeOutput's and MixDecNodeOutputId's code coverage.
        assertEquals(oneOutput.getTenantId(), TENANT_ID);
        assertEquals(oneOutput.getElectionEventId(), EE_ID);
        assertEquals(oneOutput.getBallotBoxId(), BB_ID);
        assertEquals(oneOutput.getVoteSetIndex(), VOTE_SET_INDEX);
        assertEquals(oneOutput.getPayloadJson(), payloadJson);
    }
}
