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

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.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;
import com.scytl.products.ov.vw.infrastructure.log.VwLoggingInitializationState;
import com.scytl.products.ov.vw.services.domain.model.platform.VwCertificateValidationService;
import com.scytl.products.ov.vw.services.domain.model.platform.VwLoggingKeystoreEntity;
import com.scytl.products.ov.vw.services.domain.model.platform.VwLoggingKeystoreRepository;
import com.scytl.products.ov.vw.services.domain.model.platform.VwPlatformCARepository;
import com.scytl.products.ov.vw.services.domain.model.platform.VwPlatformCaEntity;

/**
 * Endpoint for uploading the information during the installation of the platform in the system
 */
@Path("platformdata")
@Stateless(name = "vw-platformDataResource")
public class VwPlatformDataResource {

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

    private final String context = "VW";

    private final String encryptionPwPropertiesKey = "VW_log_encryption";

    private final String signingPwPropertiesKey = "VW_log_signing";

    @EJB
    @VwPlatformCARepository
    PlatformCARepository platformRepository;

    @EJB
    @VwLoggingKeystoreRepository
    LoggingKeystoreRepository loggingKeystoreRepository;

    @EJB
    VwLoggingInitializationState loggingInitializationState;

    @EJB
    @VwCertificateValidationService
    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 VwPlatformCaEntity(), new VwPlatformCaEntity());

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

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

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

            SecureLoggerInitializer secureLoggerInitializer = new SecureLoggerInitializer(loggingInitializationState,
                loggingKeystoreRepository, context, encryptionPwPropertiesKey, signingPwPropertiesKey);

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

            return Response.ok().build();

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