/*
 * 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.preconfiguration;

import static java.util.Arrays.asList;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;

import java.io.IOException;
import java.net.URISyntaxException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.HashSet;
import java.util.Set;

import javax.json.JsonObject;

import org.junit.After;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.support.AnnotationConfigContextLoader;

import com.orientechnologies.orient.core.db.document.ODatabaseDocument;
import com.orientechnologies.orient.core.metadata.schema.OClass;
import com.orientechnologies.orient.core.metadata.schema.OSchema;
import com.scytl.products.ov.commons.util.JsonUtils;
import com.scytl.products.ov.sdm.domain.config.ConfigTest;
import com.scytl.products.ov.sdm.domain.model.preconfiguration.PreconfigurationRepository;
import com.scytl.products.ov.sdm.infrastructure.DatabaseManager;
import com.scytl.products.ov.sdm.infrastructure.JsonConstants;

/**
 *
 */
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = ConfigTest.class, loader = AnnotationConfigContextLoader.class)
@ActiveProfiles("test")
public class PreconfigurationRepositoryImplTest {
    private static final Set<String> SYSTEM_CLASSES =
        new HashSet<>(asList("OFunction", "OIdentity", "ORestricted",
            "ORIDs", "ORole", "OSchedule", "OTriggered", "OUser"));

    @Autowired
    private PreconfigurationRepository repository;

    @Autowired
    private DatabaseManager manager;

    @Value("${elections.config.filename}")
    private String filename;

    @After
    public void tearDown() throws IOException {
        try (ODatabaseDocument database = manager.openDatabase()) {
            OSchema schema = database.getMetadata().getSchema();
            for (OClass oClass : schema.getClasses()) {
                if (!SYSTEM_CLASSES.contains(oClass.getName())) {
                    oClass.truncate();
                }
            }
        }
    }

    @Test
    public void readFromFileAndSave()
            throws IOException, URISyntaxException {
        Path path =
            Paths.get(ClassLoader.getSystemResource(filename).toURI());
        String result = repository
            .readFromFileAndSave(path.toAbsolutePath().toString());

        assertNotNull(result);
        JsonObject jsonObject = JsonUtils.getJsonObject(result);
        assertNotNull(jsonObject);
        assertFalse(jsonObject.isEmpty());
        assertFalse(jsonObject
            .getJsonArray(
                JsonConstants.JSON_ATTRIBUTE_NAME_ADMINISTRATION_AUTHORITIES)
            .isEmpty());
        assertFalse(jsonObject
            .getJsonArray(
                JsonConstants.JSON_ATTRIBUTE_NAME_ELECTION_EVENTS)
            .isEmpty());
        assertFalse(jsonObject
            .getJsonArray(
                JsonConstants.JSON_ATTRIBUTE_NAME_VOTING_CARD_SETS)
            .isEmpty());
        assertFalse(jsonObject
            .getJsonArray(JsonConstants.JSON_ATTRIBUTE_NAME_BALLOT_BOXES)
            .isEmpty());
    }

    @Test
    public void readFromFileAndSaveExeptionDuplicated()
            throws IOException, URISyntaxException {
        Path path =
            Paths.get(ClassLoader.getSystemResource(filename).toURI());
        repository.readFromFileAndSave(path.toAbsolutePath().toString());
        String result = repository
            .readFromFileAndSave(path.toAbsolutePath().toString());

        assertNotNull(result);
        JsonObject jsonObject = JsonUtils.getJsonObject(result);
        assertNotNull(jsonObject);
        assertFalse(jsonObject.isEmpty());
        assertTrue(jsonObject
            .getJsonArray(
                JsonConstants.JSON_ATTRIBUTE_NAME_ADMINISTRATION_AUTHORITIES)
            .isEmpty());
        assertTrue(jsonObject
            .getJsonArray(
                JsonConstants.JSON_ATTRIBUTE_NAME_ELECTION_EVENTS)
            .isEmpty());
        assertTrue(jsonObject
            .getJsonArray(
                JsonConstants.JSON_ATTRIBUTE_NAME_VOTING_CARD_SETS)
            .isEmpty());
        assertTrue(jsonObject
            .getJsonArray(JsonConstants.JSON_ATTRIBUTE_NAME_BALLOT_BOXES)
            .isEmpty());
    }
}
