/*
 * 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.channel.cc.orchestrator.ui.ws.rs.operation;

import com.scytl.products.ov.channel.cc.orchestrator.domain.platform.OrchestratorCertificateValidationService;
import com.scytl.products.ov.channel.cc.orchestrator.domain.platform.OrchestratorLoggingKeystoreEntity;
import com.scytl.products.ov.channel.cc.orchestrator.domain.platform.OrchestratorLoggingKeystoreRepository;
import com.scytl.products.ov.channel.cc.orchestrator.domain.platform.OrchestratorPlatformCARepository;
import com.scytl.products.ov.channel.cc.orchestrator.domain.platform.OrchestratorPlatformCaEntity;
import javax.ejb.EJB;
import javax.ejb.Stateless;
import javax.ws.rs.Consumes;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.scytl.cryptolib.certificates.bean.X509CertificateType;
import com.scytl.products.ov.channel.cc.orchestrator.infrastructure.logging.OrchestratorLoggingInitializationState;
import com.scytl.products.ov.commons.beans.domain.model.platform.PlatformInstallationData;
import com.scytl.products.ov.commons.beans.exceptions.DuplicateEntryException;
import com.scytl.products.ov.commons.beans.validation.CertificateValidationService;
import com.scytl.products.ov.commons.beans.validation.CryptographicOperationException;
import com.scytl.products.ov.commons.domain.model.platform.PlatformCARepository;
import com.scytl.products.ov.commons.domain.model.platform.PlatformInstallationDataHandler;
import com.scytl.products.ov.commons.logging.config.SecureLoggerInitializer;
import com.scytl.products.ov.commons.logging.domain.model.LoggingKeystoreRepository;

/**
 * Endpoint for upload the information during the installation of the platform in the system
 */
@Path(OrPlatformDataResource.RESOURCE_PATH)
@Stateless(name = "or-platformDataResource")
public class OrPlatformDataResource {

    static final String RESOURCE_PATH = "platformdata";

    private static final Logger LOG = LoggerFactory.getLogger("std");

    private static final String CONTEXT = "OR";

    private static final String ENCRYPTION_PWS_PROPERTIES_KEY = "OR_log_encryption";

    private static final String SIGNING_PWS_PROPERTIES_KEY = "OR_log_signing";    

    @EJB
    @OrchestratorPlatformCARepository
    PlatformCARepository platformRepository;

    @EJB
    @OrchestratorLoggingKeystoreRepository
    LoggingKeystoreRepository loggingKeystoreRepository;

    @EJB
    OrchestratorLoggingInitializationState loggingInitializationState;

    @EJB
    @OrchestratorCertificateValidationService
    CertificateValidationService certificateValidationService;

    /**
     * Installs the logging keystores and platform CA in the service. Additionally, this method also attempts to
     * initialize the secure logging system.
     *
     * @param data
     *            all the platform data.
     * @throws CryptographicOperationException
     * @throws DuplicateEntryException
     */
    @POST
    @Consumes(MediaType.APPLICATION_JSON)
    @Produces(MediaType.APPLICATION_JSON)
    public Response savePlatformData(final PlatformInstallationData data)
            throws CryptographicOperationException, DuplicateEntryException {

        try {

            String platformName = PlatformInstallationDataHandler.savePlatformCertificateChain(data, platformRepository,
                certificateValidationService, new OrchestratorPlatformCaEntity(), new OrchestratorPlatformCaEntity());

            String encryptionKey = data.getLoggingEncryptionKeystoreBase64();
            String signingKey = data.getLoggingSigningKeystoreBase64();

            OrchestratorLoggingKeystoreEntity encryptionKeystore = new OrchestratorLoggingKeystoreEntity();
            encryptionKeystore.setPlatformName(platformName);
            encryptionKeystore.setKeystoreContent(encryptionKey);
            encryptionKeystore.setKeyType(X509CertificateType.ENCRYPT.name());
            loggingKeystoreRepository.save(encryptionKeystore);

            OrchestratorLoggingKeystoreEntity signingKeystore = new OrchestratorLoggingKeystoreEntity();
            signingKeystore.setPlatformName(platformName);
            signingKeystore.setKeystoreContent(signingKey);
            signingKeystore.setKeyType(X509CertificateType.SIGN.name());
            loggingKeystoreRepository.save(signingKeystore);

            SecureLoggerInitializer secureLoggerInitializer = new SecureLoggerInitializer(loggingInitializationState,
                loggingKeystoreRepository, CONTEXT, ENCRYPTION_PWS_PROPERTIES_KEY, SIGNING_PWS_PROPERTIES_KEY);

            secureLoggerInitializer.initializeFromUploadData(encryptionKey, signingKey);
            LOG.info("ORCHESTRATOR - logging initialized successfully");
            loggingInitializationState.setInitialized(true);

            return Response.ok().build();

        } catch (Exception e) {
            throw new IllegalStateException("ORCHESTRATOR - error while trying to initialize logging", e);
        }
    }
}
