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

import javax.ejb.EJB;
import javax.ejb.Stateless;
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
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.au.services.domain.model.tenant.AuTenantKeystoreEntity;
import com.scytl.products.ov.au.services.domain.model.tenant.AuTenantKeystoreRepository;
import com.scytl.products.ov.au.services.infrastructure.persistence.AuTenantSystemKeys;
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("tenantdata")
@Stateless(name = "au-tenantDataResource")
public class AuTenantDataResource {

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

    private static final String TENANT_PARAMETER = "tenantId";

    private static final String CONTEXT = "AU";

    @EJB
    @AuTenantKeystoreRepository
    TenantKeystoreRepository tenantKeystoreRepository;

    @EJB
    private AuTenantSystemKeys auTenantSystemKeys;

    /**
     * Installs the tenant keystores in the service.
     *
     * @param tenantId
     *            the ID of the tenant.
     * @param data
     *            json object containing the information.
     * @return
     * @throws IllegalStateException
     */
    @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("AU - install tenant request received");

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

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

            return Response.ok().build();

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

    /**
     * Activates a tenant in the service.
     *
     * @param tenantActivationData
     *            the tenant data.
     * @return
     * @throws IllegalStateException
     */
    @POST
    @Path("activatetenant")
    @Consumes(MediaType.APPLICATION_JSON)
    @Produces(MediaType.APPLICATION_JSON)
    public Response activateTenant(final TenantActivationData tenantActivationData) {

        try {

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

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

            return Response.ok().build();

        } catch (Exception e) {
            String errorMsg = "AU - 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 validations = new ContextValidationResult.Builder().setContextName(CONTEXT)
            .setValidationType(ValidationType.TENANT_ACTIVATION).setResult(auTenantSystemKeys.getInitialized(tenantId))
            .build();
        return Response.ok(validations).build();
    }
}
