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

import org.junit.Assert;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.xml.sax.SAXException;

import javax.xml.bind.JAXBException;
import java.io.File;
import java.io.IOException;
import java.net.URISyntaxException;
import java.util.List;

import com.scytl.product.ov.sdm.plugin.PhaseName;
import com.scytl.product.ov.sdm.plugin.Plugins;
import com.scytl.products.ov.sdm.plugin.PluginSequenceResolver;
import com.scytl.products.ov.sdm.plugin.XmlObjectsLoader;

public class PluginSequenceResolverTest {

    PluginSequenceResolver commands;
    Plugins plugins;

    @Rule
    public ExpectedException exception =
            ExpectedException.none();

    @Before
    public void init() throws IOException, JAXBException, SAXException, URISyntaxException {
        plugins = XmlObjectsLoader.loadFile("/plugins_FRIBURG_test_err.xml");
        commands = new PluginSequenceResolver(plugins);
    }

    @Test
    public void get_actions_for_phase() throws URISyntaxException, IOException, JAXBException, SAXException {

        String resourcePath = this.getClass()
                .getResource("/validPlugin.xml").toURI().getPath();
        Plugins plugins =
                XmlObjectsLoader.unmarshal(new File(resourcePath).toPath());

        PluginSequenceResolver commands =
                new PluginSequenceResolver(plugins);
        List<String> actionsForPhase =
                commands.getActionsForPhase(PhaseName.GENERATE_PRE_VOTING_OUTPUTS);
        Assert.assertTrue(actionsForPhase.get(0).contains("java -jar #SDM_PATH#\\eCH\\eCH_file_converter\\ech-file-converter.jar"));
        Assert.assertTrue(actionsForPhase.get(0).contains("-action election_event_alias_to_id"));
        Assert.assertTrue(actionsForPhase.get(0).contains("-election_export_in #SDM_PATH#\\sdmConfig\\config.json"));
        Assert.assertTrue(actionsForPhase.get(0).contains("-output #SDM_PATH#\\eCH\\electionEvents\\#EE_ALIAS#\\output\\election_event_alias_to_id_#EE_ALIAS#.csv"));
        Assert.assertTrue(actionsForPhase.get(0).contains("-log #SDM_PATH#\\eCH\\electionEvents\\#EE_ALIAS#\\logs\\eCH_file_converter_#EE_ALIAS#.log"));
    }

    @Test
    public void when_command_invalid_then_validate_false_test() throws Exception {
        List<String> commandsForPhase;
        commandsForPhase = commands.getActionsForPhaseAndOrder(PhaseName.GENERATE_PRE_VOTING_OUTPUTS.value(), 11);
        Assert.assertFalse(validateParametersAndCommand(commandsForPhase.get(0)));
    }

    @Test
    public void when_missing_params_of_file_converter_then_validate_false_test() throws Exception {
        List<String> commandsForPhase;
        commandsForPhase = commands.getActionsForPhaseAndOrder(PhaseName.GENERATE_PRE_VOTING_OUTPUTS.value(), 12);
        Assert.assertFalse(validateParametersAndCommand(commandsForPhase.get(0)));
    }

    @Test
    public void when_valid_params_of_file_converter_then_validateParametersForCommand_true_test() throws Exception {
        List<String> commandsForPhase;
        commandsForPhase = commands.getActionsForPhaseAndOrder(PhaseName.GENERATE_PRE_VOTING_OUTPUTS.value(), 13);
        Assert.assertFalse(validateParametersAndCommand(commandsForPhase.get(0)));
    }

    @Test
    public void when_params_valid_of_copyTo_then_validate_true_test() throws Exception {
        List<String> commandsForPhase;
        commandsForPhase = commands.getActionsForPhaseAndOrder(PhaseName.GENERATE_PRE_VOTING_OUTPUTS.value(), 14);
        Assert.assertFalse(validateParametersAndCommand(commandsForPhase.get(0)));
    }

    @Test
    public void when_invalid_params_of_copyTo_then_validate_false_test() throws Exception {
        List<String> commandsForPhase;
        commandsForPhase = commands.getActionsForPhaseAndOrder(PhaseName.GENERATE_PRE_VOTING_OUTPUTS.value(), 15);
        Assert.assertFalse(validateParametersAndCommand(commandsForPhase.get(0)));
    }

    @Test
    public void when_exists_params_copyFrom_then_validate_false_test() throws Exception {
        List<String> commandsForPhase;
        commandsForPhase = commands.getActionsForPhaseAndOrder(PhaseName.GENERATE_PRE_VOTING_OUTPUTS.value(), 16);
        Assert.assertFalse(validateParametersAndCommand(commandsForPhase.get(0)));
    }

    /**
     * Validate parameters of the in action
     *
     * @param actionForPhase
     * @return
     */
    private boolean validateParametersAndCommand(String actionForPhase) {
        boolean result = true;
        if(!actionForPhase.contains("ech-file-converter.jar")
                || !actionForPhase.contains("copyToUsb.bat")
                || !actionForPhase.contains("copyFromUsb.bat")) {
            result = false;
        } else {
            if (actionForPhase.contains("ech-file-converter.jar")) {
                String[] params = actionForPhase.split(" -");
                if (params.length <= 2) {
                    result = false;
                } else {
                    result = true;
                }
            } else if (actionForPhase.contains("copyToUsb.bat")) {
                String[] params = actionForPhase.split(" ");
                if (params.length != 4
                        || !((actionForPhase.contains("#USB_LETTER#"))
                        && (actionForPhase.contains("#EE_ID#"))
                        && (actionForPhase.contains("#EE_ALIAS#")))) {
                    result = false;
                }
            } else if (actionForPhase.contains("copyFromUsb.bat")) {
                if (actionForPhase.length() > 0) {
                    result = false;
                }
            }
        }
        return result;
    }
}
