/*
 * 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.vv.ui.ws.rs.application.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.vv.domain.model.platform.VvCertificateValidationService;
import com.scytl.products.ov.vv.domain.model.platform.VvLoggingKeystoreEntity;
import com.scytl.products.ov.vv.domain.model.platform.VvLoggingKeystoreRepository;
import com.scytl.products.ov.vv.domain.model.platform.VvPlatformCARepository;
import com.scytl.products.ov.vv.domain.model.platform.VvPlatformCaEntity;
import com.scytl.products.ov.vv.infrastructure.log.VvLoggingInitializationState;

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

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

    private static final String CONTEXT = "VV";

    private static final String ENCRYPTION_PW_PROPERTIES_KEY = "VV_log_encryption";

    private static final String SIGNING_PW_PROPERTIES_KEY = "VV_log_signing";

    @EJB
    @VvPlatformCARepository
    PlatformCARepository platformRepository;

    @EJB
    @VvLoggingKeystoreRepository
    LoggingKeystoreRepository loggingKeystoreRepository;

    @EJB
    VvLoggingInitializationState loggingInitializationState;

    @EJB
    @VvCertificateValidationService
    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 VvPlatformCaEntity(), new VvPlatformCaEntity());

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

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

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

            SecureLoggerInitializer secureLoggerInitializer = new SecureLoggerInitializer(loggingInitializationState,
                loggingKeystoreRepository, CONTEXT, ENCRYPTION_PW_PROPERTIES_KEY, SIGNING_PW_PROPERTIES_KEY);

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

            return Response.ok().build();

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