/*
 * 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.sdm.infrastructure.keytranslation;

import java.security.PrivateKey;

import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.WebTarget;
import javax.ws.rs.core.Response;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Repository;

import com.scytl.products.ov.commons.infrastructure.exception.OvCommonsInfrastructureException;
import com.scytl.products.ov.commons.infrastructure.remote.client.NodeIdentifier;
import com.scytl.products.ov.commons.infrastructure.remote.client.RestClientConnectionManager;
import com.scytl.products.ov.commons.infrastructure.remote.client.RetrofitConsumer;
import com.scytl.products.ov.commons.infrastructure.remote.client.RetrofitException;
import com.scytl.products.ov.sdm.application.service.KeyStoreService;
import com.scytl.products.ov.sdm.domain.model.keytranslation.BallotBoxTranslationList;
import com.scytl.products.ov.sdm.domain.model.keytranslation.ElectionEventTranslationList;
import com.scytl.products.ov.sdm.domain.model.keytranslation.KeyTranslationUploadRepository;
import com.scytl.products.ov.sdm.infrastructure.clients.KeyTranslationClient;
import com.scytl.products.ov.sdm.infrastructure.exception.KeyTranslationUploadRepositoryException;

import okhttp3.ResponseBody;
import retrofit2.Retrofit;


@Repository
public class KeyTranslationUploadRepositoryImpl implements KeyTranslationUploadRepository {

    private static final String TENANT_ID_PARAM = "tenantId";

    private static final String ELECTION_EVENT_ID_PARAM = "electionEventId";

    private static final String CHECK_IF_EXISTS_URL = "/electionevent/tenant/{tenantId}/electionEvent/{electionEventId}";

    private static final String API_GATEWAY_URL = "/check/ready";

    private static final Logger LOGGER = LoggerFactory.getLogger(KeyTranslationUploadRepository.class);

    @Value("${EA_URL}")
    private String apiGatewayURL;

    @Value("${KT_URL}")
    private String keyTranslationURL;

    @Value("${tenantID}")
    private String tenantId;

    @Autowired
    KeyStoreService keyStoreService;

    @Override
    public boolean checkHealthAG() {

        WebTarget target = ClientBuilder.newClient().target(apiGatewayURL);
        Response response = target.path(API_GATEWAY_URL).request().get();

        return response.getStatus() == Response.Status.OK.getStatusCode();
    }

    @Override
	public boolean createUpdateElectionEventKeyTranslations(ElectionEventTranslationList translations) {

        boolean result = false;
        if (!checkHealthAG()) {
            LOGGER.error("Connection refused to AG. Skipping Key translation upload");
        } else {
            Retrofit restAdapter = null;
            try {
                PrivateKey requestSigningKey = keyStoreService.getPrivateKey();
                restAdapter = RestClientConnectionManager.getInstance().getRestClientWithInterceptorAndJacksonConverter(keyTranslationURL,
                    requestSigningKey, NodeIdentifier.SECURE_DATA_MANAGER);
            } catch (OvCommonsInfrastructureException e) {
                LOGGER.error("There was an error trying to upload key translation");
                throw new KeyTranslationUploadRepositoryException("There was an error trying to upload key translation", e);
            }
            KeyTranslationClient ktClient = restAdapter.create(KeyTranslationClient.class);
			try (ResponseBody responseBody = RetrofitConsumer
					.processResponse(ktClient.createUpdateElectionEventKeyTranslation(tenantId, translations))) {
				LOGGER.info("Key translation uploaded successfully");
				result = true;
			} catch (RetrofitException e) {
				LOGGER.error("There was an error trying to upload key translation", e);
			}
        }
        return result;
    }

    @Override
    public boolean
    createUpdateBallotBoxKeyTranslations(String electionEventId, BallotBoxTranslationList translations) {

        boolean result = false;
        Retrofit restAdapter = null;
        try {
            PrivateKey requestSigningKey = keyStoreService.getPrivateKey();
            restAdapter = RestClientConnectionManager.getInstance().getRestClientWithInterceptorAndJacksonConverter(keyTranslationURL,
                requestSigningKey, NodeIdentifier.SECURE_DATA_MANAGER);
        } catch (OvCommonsInfrastructureException e) {
            LOGGER.error("There was an error trying to upload key translation");
            throw new KeyTranslationUploadRepositoryException("There was an error trying to upload key translation", e);
        }
        KeyTranslationClient ktClient = restAdapter.create(KeyTranslationClient.class);
		try (ResponseBody responseBody = RetrofitConsumer
				.processResponse(ktClient.createUpdateBallotBoxKeyTranslation(tenantId, translations))) {
			LOGGER.info("Key translation uploaded successfully");
			result = true;
		} catch (RetrofitException e) {
			LOGGER.error("There was an error trying to upload key translation", e);
		}
        return result;
    }

    /**
     * Checks if for a given election eventId , already exists the key translation
     *
     * @param electionEventId
     * @return
     */
    @Override
    public boolean isAlreadyUploaded(String electionEventId) {

        boolean result = false;

        WebTarget target = ClientBuilder.newClient().target(keyTranslationURL);

        Response response = target.path(CHECK_IF_EXISTS_URL).resolveTemplate(TENANT_ID_PARAM, tenantId)
            .resolveTemplate(ELECTION_EVENT_ID_PARAM, electionEventId).request().get();

        if (response.getStatus() == Response.Status.OK.getStatusCode()) {
            LOGGER.info(String.format("Key translation already uploaded for the election event %s", electionEventId));
            result = true;
        }

        return result;

    }

}
