/*
 * 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.cr.services.domain.model.service;

import java.security.cert.Certificate;

import javax.ejb.Stateless;
import javax.inject.Inject;

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

import com.scytl.cryptolib.api.exceptions.GeneralCryptoLibException;
import com.scytl.cryptolib.certificates.bean.X509DistinguishedName;
import com.scytl.cryptolib.certificates.configuration.X509CertificateValidationResult;
import com.scytl.cryptolib.certificates.cryptoapi.CryptoAPIX509Certificate;
import com.scytl.cryptolib.primitives.primes.utils.PemUtils;
import com.scytl.products.ov.commons.beans.exceptions.DuplicateEntryException;
import com.scytl.products.ov.commons.beans.exceptions.ResourceNotFoundException;
import com.scytl.products.ov.commons.beans.validation.CertificateValidationService;
import com.scytl.products.ov.commons.beans.validation.CryptographicOperationException;
import com.scytl.products.ov.cr.services.domain.model.certificate.CertificateEntity;
import com.scytl.products.ov.cr.services.domain.model.certificate.CertificateRepository;
import com.scytl.products.ov.cr.services.domain.model.platform.CrCertificateValidationService;
import com.scytl.products.ov.cr.services.utils.CertificateTools;

@Stateless
public class CertificateService {

	private static final Logger LOG = LoggerFactory.getLogger("std");
    
    @Inject
    @CrCertificateValidationService
    private CertificateValidationService certificateValidationService;
    
    @Inject
    CertificateRepository certificateRepository;

    /**
     * Saves an intermediate or root CA into the repository
     *
     * @param certificateEntity
     * @return
     * @throws GeneralCryptoLibException
     * @throws DuplicateEntryException
     * @throws ResourceNotFoundException
     * @throws CryptographicOperationException
     */
    public X509CertificateValidationResult saveCertificateInDB(final CertificateEntity certificateEntity)
            throws GeneralCryptoLibException, DuplicateEntryException, ResourceNotFoundException,
            CryptographicOperationException {

        LOG.info("CR - Saving certificate to DB");

        Certificate certificate = PemUtils.certificateFromPem(certificateEntity.getCertificateContent());

        CryptoAPIX509Certificate cryptoAPIX509Certificate = CertificateTools.getCryptoX509Certificate(certificate);

        final X509DistinguishedName subjectDN = cryptoAPIX509Certificate.getSubjectDn();
        certificateEntity.setPlatformName(subjectDN.getOrganization());
        certificateEntity.setCertificateName(subjectDN.getCommonName());

        String issuerCommonName = cryptoAPIX509Certificate.getIssuerDn().getCommonName();
        String subjectCommonName = cryptoAPIX509Certificate.getSubjectDn().getCommonName();
        X509CertificateValidationResult validationResult;

        if (!issuerCommonName.equals(subjectCommonName)) {

            LOG.info("CR - issuer and subject common names are equal");

            CertificateEntity parentEntity = certificateRepository.findByName(issuerCommonName);

            Certificate parentCertificate = PemUtils.certificateFromPem(parentEntity.getCertificateContent());

            validationResult =
                certificateValidationService.validateIntermediateCACertificate(certificate, parentCertificate);

        } else {

            LOG.info("CR - issuer and subject common names are not equal");

            validationResult = certificateValidationService.validateRootCertificate(certificate);
        }
        if (validationResult.isValidated()) {

            LOG.info("CR - validation has passed - will save in repository");

            certificateRepository.save(certificateEntity);
            LOG.info("CR - certificate saved.");
        }
        return validationResult;
    }

}
