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

import java.io.File;
import java.net.URISyntaxException;
import java.net.URL;
import java.nio.file.Path;

import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import com.scytl.cryptolib.api.exceptions.GeneralCryptoLibException;
import com.scytl.cryptolib.api.primitives.PrimitivesServiceAPI;
import com.scytl.cryptolib.api.symmetric.SymmetricServiceAPI;
import com.scytl.cryptolib.primitives.service.PrimitivesService;
import com.scytl.cryptolib.symmetric.service.SymmetricService;
import com.scytl.products.ov.config.actions.ExtendedAuthenticationService;
import com.scytl.products.ov.config.model.authentication.AuthKeyGeneratorBeyondLimit;
import com.scytl.products.ov.config.model.authentication.AuthenticationKeyGenerator;
import com.scytl.products.ov.config.model.authentication.AuthenticationKeyGeneratorStrategyType;
import com.scytl.products.ov.config.model.authentication.ChallengeGenerator;
import com.scytl.products.ov.config.model.authentication.ChallengeGeneratorStrategyType;
import com.scytl.products.ov.config.model.authentication.LongSecretsAuthKeyGenerator;
import com.scytl.products.ov.config.model.authentication.service.AuthenticationGeneratorFactory;
import com.scytl.products.ov.config.model.authentication.service.AuthenticationKeyCryptoService;
import com.scytl.products.ov.config.model.authentication.service.ChallengeGeneratorFactory;
import com.scytl.products.ov.config.model.authentication.service.ChallengeService;
import com.scytl.products.ov.config.model.authentication.service.ChallengeServiceAPI;
import com.scytl.products.ov.config.model.authentication.service.ProvidedChallengeSource;
import com.scytl.products.ov.config.model.authentication.service.SequentialProvidedChallengeSource;
import com.scytl.products.ov.config.model.authentication.service.StartVotingKeyService;

@Configuration
public class SpringConfigTest {

    @Bean
    SymmetricServiceAPI symmetricServiceAPI() throws GeneralCryptoLibException {
        return new SymmetricService();
    }

    @Bean
    PrimitivesServiceAPI primitivesServiceAPI() throws GeneralCryptoLibException {
        return new PrimitivesService();
    }

    @Bean
    AuthenticationKeyCryptoService authKeyService() {
        return new AuthenticationKeyCryptoService();
    }

    @Bean
    public ProvidedChallengeSource providedChallengeSource() throws URISyntaxException {
        final URL url = this.getClass().getResource("/aliasDataSample.csv");
        Path aliasesPath = new File(url.toURI()).toPath();
        return new SequentialProvidedChallengeSource(aliasesPath);
    }

    @Bean
    ChallengeGeneratorFactory challengeGeneratorFactory() {
        return new ChallengeGeneratorFactory();
    }

    @Bean
    ChallengeGenerator challengeGenerator(final ChallengeGeneratorFactory challengeGeneratorFactory) {
        return challengeGeneratorFactory.createStrategy(ChallengeGeneratorStrategyType.NONE);
    }

    @Bean
    ChallengeServiceAPI challengeService(final PrimitivesServiceAPI primitivesService,
            final ChallengeGenerator challengeGenerator) {
        return new ChallengeService(primitivesService, challengeGenerator);
    }

    @Bean
    AuthenticationGeneratorFactory authenticationGeneratorFactory() {
        return new AuthenticationGeneratorFactory();
    }

    @Bean
    @Qualifier("SIMPLE")
    AuthenticationKeyGenerator simpleAuthenticationKeyGeneratorStrategy(
            final AuthenticationGeneratorFactory authenticationGeneratorFactory) {
        return authenticationGeneratorFactory.createStrategy(AuthenticationKeyGeneratorStrategyType.SIMPLE);
    }

    @Bean
    @Qualifier("MULTISECRET")
    AuthenticationKeyGenerator multisecretAuthenticationKeyGeneratorStrategy(
            final AuthenticationGeneratorFactory authenticationGeneratorFactory) {
        return authenticationGeneratorFactory.createStrategy(AuthenticationKeyGeneratorStrategyType.MULTISECRET);
    }

    @Bean
    @Qualifier("LONGSECRETS")
    AuthenticationKeyGenerator longSecretsAuthenticationKeyGeneratorStrategy() {
        return new LongSecretsAuthKeyGenerator();
    }

    @Bean
    @Qualifier("BEYONDLIMIT")
    AuthenticationKeyGenerator authenticationKeyGeneratorBeyondLimit() {
        return new AuthKeyGeneratorBeyondLimit();
    }

    @Bean
    ExtendedAuthenticationService createAndHandleAuthKey(final AuthenticationKeyCryptoService authKeyService,
            @Qualifier("SIMPLE") final AuthenticationKeyGenerator authenticationKeyGenerator,
            final ChallengeServiceAPI challengeService) {
        return new ExtendedAuthenticationService(authKeyService, authenticationKeyGenerator, challengeService);
    }

    @Bean
    StartVotingKeyService startVotingKeyService(
            @Qualifier("MULTISECRET") final AuthenticationKeyGenerator authenticationKeyGenerator) {
        return new StartVotingKeyService(authenticationKeyGenerator);
    }

    @Bean
    @Qualifier("LONGSECRETS")
    StartVotingKeyService startVotingKeyServiceWithLongSecrets(
            @Qualifier("LONGSECRETS") final AuthenticationKeyGenerator authenticationKeyGenerator) {
        return new StartVotingKeyService(authenticationKeyGenerator);
    }

    @Bean
    @Qualifier("BEYONDLIMIT")
    StartVotingKeyService startVotingKeyServiceBeyondLimit(
            @Qualifier("BEYONDLIMIT") final AuthenticationKeyGenerator authenticationKeyGenerator) {
        return new StartVotingKeyService(authenticationKeyGenerator);
    }

    @Bean
    AuthenticationKeyCryptoService authenticationKeyCryptoService() {
        return new AuthenticationKeyCryptoService();
    }

}
