/*
 * 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 javax.ejb.EJB;
import javax.ejb.Stateless;
import javax.ws.rs.*;
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.domain.model.tenant.OrTenantKeystoreEntity;
import com.scytl.products.ov.channel.cc.orchestrator.domain.model.tenant.OrTenantKeystoreRepository;
import com.scytl.products.ov.channel.cc.orchestrator.domain.model.tenant.OrTenantSystemKeys;
import com.scytl.products.ov.commons.beans.domain.model.tenant.TenantActivationData;
import com.scytl.products.ov.commons.beans.domain.model.tenant.TenantInstallationData;
import com.scytl.products.ov.commons.beans.validation.ContextValidationResult;
import com.scytl.products.ov.commons.beans.validation.ValidationType;
import com.scytl.products.ov.commons.domain.model.tenant.TenantKeystoreRepository;
import com.scytl.products.ov.commons.tenant.TenantActivator;

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

    static final String RESOURCE_PATH = "tenantdata";

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

    private static final String TENANT_PARAMETER = "tenantId";

    private static final String CONTEXT = "OR";

    @EJB
    @OrTenantKeystoreRepository
    TenantKeystoreRepository tenantKeystoreRepository;

    @EJB
    private OrTenantSystemKeys orTenantSystemKeys;

    /**
     * Installs the tenant keystores in the Service
     *
     * @param data,
     *            json object containing the information
     * @return
     * @throws Exception
     */
    @POST
    @Path("/tenant/{tenantId}")
    @Consumes(MediaType.APPLICATION_JSON)
    @Produces(MediaType.APPLICATION_JSON)
    public Response saveTenantData(@PathParam(TENANT_PARAMETER) final String tenantId,
                                   final TenantInstallationData data) {

        try {

            LOG.info("OR - install tenant request received");

            OrTenantKeystoreEntity tenantKeystoreEntity = new OrTenantKeystoreEntity();
            tenantKeystoreEntity.setKeystoreContent(data.getEncodedData());
            tenantKeystoreEntity.setTenantId(tenantId);
            tenantKeystoreEntity.setKeyType(X509CertificateType.ENCRYPT.name());

            tenantKeystoreRepository.save(tenantKeystoreEntity);

            TenantActivator tenantActivator =
                    new TenantActivator(tenantKeystoreRepository, orTenantSystemKeys, CONTEXT);
            tenantActivator.activateUsingReceivedKeystore(tenantId, data.getEncodedData());

            return Response.ok().build();

        } catch (Exception e) {
            String errorMsg = "OR - error while trying to install a tenant: " + e.getMessage();
            LOG.error(errorMsg);
            throw new IllegalStateException(errorMsg, e);
        }
    }

    @POST
    @Path("activatetenant")
    @Consumes(MediaType.APPLICATION_JSON)
    @Produces(MediaType.APPLICATION_JSON)
    public Response activateTenant(final TenantActivationData tenantActivationData) {

        try {

            LOG.info("OR - activate tenant request received");

            TenantActivator tenantActivator =
                    new TenantActivator(tenantKeystoreRepository, orTenantSystemKeys, CONTEXT);
            tenantActivator.activateFromDB(tenantActivationData);

            return Response.ok().build();

        } catch (Exception e) {
            String errorMsg = "OR - error while trying to install a tenant: " + e.getMessage();
            LOG.error(errorMsg);
            throw new IllegalStateException(errorMsg, e);
        }
    }

    /**
     * Check if a tenant has been activated for this context
     *
     * @param tenantId
     *            - identifier of the tenant
     * @return
     */
    @GET
    @Path("activatetenant/tenant/{tenantId}")
    @Produces(MediaType.APPLICATION_JSON)
    public Response checkTenantActivation(@PathParam(TENANT_PARAMETER) final String tenantId) {

        ContextValidationResult validation = new ContextValidationResult.Builder().setContextName(CONTEXT)
                .setValidationType(ValidationType.TENANT_ACTIVATION).setResult(orTenantSystemKeys.getInitialized(tenantId))
                .build();
        return Response.ok(validation).build();
    }
}
