/*
 * 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.model.authentication.service;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

import com.scytl.products.ov.config.model.authentication.AuthSecretSpec;
import com.scytl.products.ov.config.model.authentication.AuthenticationKey;
import com.scytl.products.ov.config.model.authentication.AuthenticationKeyGenerator;
import com.scytl.products.ov.config.model.authentication.StartVotingKey;
import com.scytl.products.ov.config.model.authentication.service.impl.AuthSecretsGeneratorImpl;
import com.scytl.products.ov.constants.Constants;

/**
 * Strategy for generating the Authentication key based on two secrets, identifier and password usually.
 */
public class MultipleSecretAuthenticationKeyGenerator implements AuthenticationKeyGenerator {

    private final List<AuthSecretSpec> secretSpecs;

    private final AuthSecretsGenerator authSecretsGenerator;

    private final String alphabet;

    public MultipleSecretAuthenticationKeyGenerator() {

        this.secretSpecs = new ArrayList<>();
        this.alphabet = "ABCDEFGHJKMNPQRSTUVWXYZabcdefghjkmnopqrstuvwxyz23456789";
        AuthSecretSpec authSecretSpec1 = new AuthSecretSpec(Constants.IDENTIFIER, 12);
        AuthSecretSpec authSecretSpec2 = new AuthSecretSpec(Constants.PW, 12);

        this.secretSpecs.add(authSecretSpec1);
        this.secretSpecs.add(authSecretSpec2);
        this.authSecretsGenerator = new AuthSecretsGeneratorImpl(alphabet);
    }

    @Override
    public AuthenticationKey generateAuthKey(final StartVotingKey startVotingKey) {

        List<String> secrets = authSecretsGenerator.generate(secretSpecs);
        String value = secrets.stream().collect(Collectors.joining());
        return AuthenticationKey.ofSecrets(value, Optional.of(secrets));
    }

    @Override
    public String getAlphabet() {
        return alphabet;
    }

    @Override
    public int getSecretsLength() {
		return secretSpecs.stream().mapToInt(x -> x.getLength()).sum();
    }
}
