/*
 * 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.config.webapp.mvc.commands.electionevent;

import java.nio.file.Path;
import java.nio.file.Paths;
import java.time.Instant;
import java.time.ZoneOffset;
import java.time.ZonedDateTime;

import org.springframework.web.bind.annotation.RequestBody;

import com.scytl.products.ov.commons.beans.AuthenticationParams;
import com.scytl.products.ov.commons.beans.ElectionInformationParams;
import com.scytl.products.ov.commons.beans.VotingWorkflowContextData;
import com.scytl.products.ov.config.commands.electionevent.CreateElectionEventParametersHolder;
import com.scytl.products.ov.config.commands.electionevent.datapacks.beans.ElectionInputDataPack;
import com.scytl.products.ov.config.webapp.mvc.dto.input.CreateElectionEventInput;
import com.scytl.products.ov.constants.Constants;
import com.scytl.products.ov.datapacks.beans.CreateElectionEventCertificatePropertiesContainer;
import com.scytl.products.ov.datapacks.helpers.ReplacementsHolder;

public class ElectionEventWebappAdapter {

    public CreateElectionEventParametersHolder adapt(@RequestBody final CreateElectionEventInput input) {
        ElectionInputDataPack electionInputDataPack = new ElectionInputDataPack();

        // get EEID parameter
        String eeid = input.getEeid();
        electionInputDataPack.setEeid(eeid);
        ReplacementsHolder replacementHolder = new ReplacementsHolder(eeid);
        electionInputDataPack.setReplacementsHolder(replacementHolder);

        String end = input.getEnd();
        Integer validityPeriod = input.getValidityPeriod();

        // ISO_INSTANT format => 2011-12-03T10:15:30Z
        ZonedDateTime startValidityPeriod = ZonedDateTime.now(ZoneOffset.UTC);
        ZonedDateTime electionEndDate = ZonedDateTime.ofInstant(Instant.parse(end), ZoneOffset.UTC);
        ZonedDateTime endValidityPeriod = electionEndDate.plusYears(validityPeriod);

        if (electionEndDate.isAfter(endValidityPeriod)) {
            throw new IllegalArgumentException("End date cannot be after Start date plus validity period.");
        }

        electionInputDataPack.setStartDate(startValidityPeriod);
        electionInputDataPack.setEndDate(endValidityPeriod);

        String challengeResExpTime = input.getChallengeResExpTime();
        String authTokenExpTime = input.getAuthTokenExpTime();
        String challengeLength = input.getChallengeLength();
        String numVotesPerVotingCard = input.getNumVotesPerVotingCard();
        String numVotesPerAuthToken = input.getNumVotesPerAuthToken();
        String maxNumberOfAttempts = input.getMaxNumberOfAttempts();

        ElectionInformationParams electionInformationParams =
            new ElectionInformationParams(numVotesPerVotingCard, numVotesPerAuthToken);

        AuthenticationParams authenticationParams =
            new AuthenticationParams(challengeResExpTime, authTokenExpTime, challengeLength);

        VotingWorkflowContextData votingWorkflowContextData = new VotingWorkflowContextData();
        votingWorkflowContextData.setMaxNumberOfAttempts(maxNumberOfAttempts);

        String outputPath = input.getOutputPath();

        Path electionFolder = Paths.get(outputPath, eeid);

        Path offlinePath = electionFolder.resolve(Constants.OFFLINE_DIRECTORY);

        Path onlinePath = electionFolder.resolve(Constants.ONLINE_DIRECTORY);

        Path autenticationPath = onlinePath.resolve(Constants.AUTHENTICATION_DIRECTORY);

        Path electionInformationPath = onlinePath.resolve(Constants.ELECTION_INFORMATION_DIRECTORY);

        Path votingWorkflowPath = onlinePath.resolve(Constants.VOTING_WORKFLOW_DIRECTORY);

        String keyForProtectingKeystorePassword = input.getKeyForProtectingKeystorePassword();

        CreateElectionEventCertificatePropertiesContainer certificatePropertiesInput = input.getCertificatePropertiesInput();

        return new CreateElectionEventParametersHolder(electionInputDataPack, Paths.get(outputPath), electionFolder,
            offlinePath, autenticationPath, electionInformationPath, votingWorkflowPath, authenticationParams,
            electionInformationParams, votingWorkflowContextData, keyForProtectingKeystorePassword,
            certificatePropertiesInput);
    }
}
