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

import java.io.IOException;
import java.net.URISyntaxException;
import java.security.GeneralSecurityException;
import java.security.cert.CertificateException;

import org.apache.commons.configuration.ConfigurationException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.scytl.cryptolib.api.exceptions.GeneralCryptoLibException;
import com.scytl.products.ov.config.tenant.ValidationException;
import com.scytl.products.ov.config.tenant.service.ConfigTenantService;
import com.scytl.products.ov.utils.PasswordReaderUtils;

/**
 * Main class in charge of execute the three configuration steps (adapt, generate and serialize) for the command
 * ordered.
 */
@Service
public class ConfigurationCommandLine {

    private static final Logger LOG = LoggerFactory.getLogger(ConfigurationCommandLine.class);

    @Autowired
    ConfigTenantService configTenantService;

    /**
     * Creates a new CSR certificate for the provided tenant
     *
     * @param receivedParameters
     */
    public void generateTenantConfiguration(final Parameters receivedParameters) {

        char[] password = PasswordReaderUtils.readPasswordFromConsoleAndConfirm();

        LOG.info("Starting the generation of CSR...");

        LOG.info("Collecting parameters...");

        String tenantName =
            String.valueOf(receivedParameters.getParam(CommandParameter.TENANT_NAME.getParameterName()));

        String ouputFolder = String.valueOf(receivedParameters.getParam(CommandParameter.OUTPUT.getParameterName()));

        final GenerateTenantParametersHolder holder = new GenerateTenantParametersHolder(tenantName, ouputFolder);

        configTenantService.generateCSRandKeystore(password, holder);

        LOG.info("The generation of the tenant CSR finished correctly.");
    }

    /**
     * Updates the keystore for the provided tenant
     *
     * @param receivedParameters
     */
    public void updateTenantKeystore(final Parameters receivedParameters)
            throws IOException, GeneralCryptoLibException, ValidationException, CertificateException {

        LOG.info("Starting to update tenant keystore...");

        char[] password = PasswordReaderUtils.readPasswordFromConsole();

        LOG.info("Collecting parameters...");

        UpdateTenantParametersAdapter adapter = new UpdateTenantParametersAdapter();

        final UpdateTenantParametersHolder holder = adapter.adapt(receivedParameters);

        configTenantService.updateTenantKeystore(password, holder);

        LOG.info("Updated the tenant keystore correctly.");
    }

    /**
     * @param args
     * @throws GeneralCryptoLibException
     * @throws IOException
     * @throws URISyntaxException
     * @throws ConfigurationException
     * @throws GeneralSecurityException
     */
    public void run(final String[] args)
            throws GeneralCryptoLibException, IOException, URISyntaxException, ConfigurationException,
            GeneralSecurityException, ValidationException {

        final Command processedCommand = MainParametersProcessor.process(args);

        if (processedCommand == null) {
            return;
        }

        final MutuallyExclusiveCommand action = processedCommand.getIdentifier();

        switch (action) {
        case HELP:
            // Nothing to do, is done inside MainParametersProcessor.process
            break;
        case GENERATE_TENANT:
            generateTenantConfiguration(processedCommand.getParameters());
            break;
        case UPDATE_KEYSTORE:
            updateTenantKeystore(processedCommand.getParameters());
            break;
        default:
            break;
        }
    }

}
