/*
 * 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.sdm.infrastructure.votingcardset;

import static java.util.Collections.singletonList;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

import java.io.IOException;
import java.net.URL;

import javax.json.Json;
import javax.json.JsonArray;
import javax.json.JsonObject;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import com.orientechnologies.common.exception.OException;
import com.scytl.products.ov.commons.util.JsonUtils;
import com.scytl.products.ov.sdm.application.exception.DatabaseException;
import com.scytl.products.ov.sdm.domain.model.ballot.BallotRepository;
import com.scytl.products.ov.sdm.domain.model.ballotbox.BallotBoxRepository;
import com.scytl.products.ov.sdm.infrastructure.DatabaseFixture;
import com.scytl.products.ov.sdm.infrastructure.DatabaseManager;
import com.scytl.products.ov.sdm.infrastructure.JsonConstants;

/**
 * Tests of {@link VotingCardSetRepositoryImpl}.
 */
public class VotingCardSetRepositoryImplTest {
    private DatabaseFixture fixture;

    private DatabaseManager manager;

    private BallotBoxRepository ballotBoxRepository;

    private BallotRepository ballotRepository;

    private VotingCardSetRepositoryImpl repository;

    @Before
    public void setUp() throws OException, IOException {
        fixture = new DatabaseFixture(getClass());
        fixture.setUp();
        manager = fixture.databaseManager();
        ballotBoxRepository = mock(BallotBoxRepository.class);
        ballotRepository = mock(BallotRepository.class);
        repository = new VotingCardSetRepositoryImpl(manager);
        repository.ballotBoxRepository = ballotBoxRepository;
        repository.ballotRepository = ballotRepository;
        repository.initialize();
        URL resource =
            getClass().getResource(getClass().getSimpleName() + ".json");
        fixture.createDocuments(repository.entityName(), resource);
    }

    @After
    public void tearDown() {
        fixture.tearDown();
    }

    @Test
    public void testGetBallotBoxId() {
        assertEquals("268872255b9b44f39c5404f3ebd85c07",
            repository.getBallotBoxId("1d9bf23fecd24f899c30b11fe1a6cb5f"));
    }

    @Test
    public void testGetBallotBoxIdNotFound() {
        assertTrue(
            repository.getBallotBoxId("unknownVotingCardSet").isEmpty());
    }

    @Test
    public void testUpdateRelatedBallot() {
        JsonObject ballotBox = Json.createObjectBuilder()
            .add(JsonConstants.JSON_ATTRIBUTE_NAME_ALIAS, "ballotBoxAlias")
            .add(JsonConstants.JSON_ATTRIBUTE_NAME_BALLOT,
                Json.createObjectBuilder()
                    .add(JsonConstants.JSON_ATTRIBUTE_NAME_ID, "ballotId"))
            .build();
        when(ballotBoxRepository.find("268872255b9b44f39c5404f3ebd85c07"))
            .thenReturn(ballotBox.toString());
        JsonObject ballot = Json.createObjectBuilder()
            .add(JsonConstants.JSON_ATTRIBUTE_NAME_ALIAS, "ballotAlias")
            .build();
        when(ballotRepository.find("ballotId"))
            .thenReturn(ballot.toString());
        repository.updateRelatedBallot(
            singletonList("1d9bf23fecd24f899c30b11fe1a6cb5f"));
        String json = repository.find("1d9bf23fecd24f899c30b11fe1a6cb5f");
        JsonObject object = JsonUtils.getJsonObject(json);
        assertEquals("ballotBoxAlias", object.getString(
            JsonConstants.JSON_ATTRIBUTE_NAME_BALLOT_BOX_ALIAS));
        assertEquals("ballotAlias", object
            .getString(JsonConstants.JSON_ATTRIBUTE_NAME_BALLOT_ALIAS));
    }

    @Test
    public void testUpdateRelatedVerificationCardSet() {
        repository.updateRelatedVerificationCardSet(
            "1d9bf23fecd24f899c30b11fe1a6cb5f", "verificationCardSetId");
        String json = repository.find("1d9bf23fecd24f899c30b11fe1a6cb5f");
        assertEquals("verificationCardSetId",
            JsonUtils.getJsonObject(json).getString(
                JsonConstants.JSON_ATTRIBUTE_NAME_VERIFICATIONCARDSETID));
    }

    @Test(expected = DatabaseException.class)
    public void testUpdateRelatedVerificationCardSetNotFound() {
        repository.updateRelatedVerificationCardSet("unknownVotingCardSet",
            "verificationCardSetId");
    }

    @Test
    public void testListByElectionEvent() {
        String json = repository
            .listByElectionEvent("101549c5a4a04c7b88a0cb9be8ab3df6");
        JsonArray array = JsonUtils.getJsonObject(json)
            .getJsonArray(JsonConstants.JSON_ATTRIBUTE_NAME_RESULT);
        assertEquals(1, array.size());
        JsonObject object = array.getJsonObject(0);
        assertEquals("1d9bf23fecd24f899c30b11fe1a6cb5f",
            object.getString(JsonConstants.JSON_ATTRIBUTE_NAME_ID));

    }

    @Test
    public void testListByElectionEventUnknown() {
        String json =
            repository.listByElectionEvent("unknownElectionEvent");
        JsonArray array = JsonUtils.getJsonObject(json)
            .getJsonArray(JsonConstants.JSON_ATTRIBUTE_NAME_RESULT);
        assertTrue(array.isEmpty());
    }
}
