/*
 * 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.application.service;

import com.scytl.products.oscore.logging.api.domain.Level;
import com.scytl.products.oscore.logging.api.domain.LogContent;
import com.scytl.products.oscore.logging.api.writer.SecureLoggingWriter;
import com.scytl.products.ov.sdm.application.log.SdmSecureLogEvent;
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.Service;

import java.io.IOException;
import java.util.Arrays;

import com.scytl.products.ov.sdm.domain.model.keytranslation.BallotBoxTranslation;
import com.scytl.products.ov.sdm.domain.model.keytranslation.BallotBoxTranslationList;
import com.scytl.products.ov.sdm.domain.model.keytranslation.ElectionEventTranslation;
import com.scytl.products.ov.sdm.domain.model.keytranslation.ElectionEventTranslationList;
import com.scytl.products.ov.sdm.domain.model.keytranslation.KeyTranslationUploadRepository;
import static com.scytl.products.ov.sdm.application.constant.Constants.NULL_ELECTION_EVENT_ID;

@Service
public class KeyTranslationUploadService {

    public static final String ELECTION_EVENT_TRANSLATIONS = "translations";

    public static final String TENANT_ID = "tenantId";

    public static final String ELECTION_EVENT_ID = "electionEventId";

    public static final String ELECTION_EVENT_ALIAS = "alias";

    @Autowired
    private ElectionEventService electionEventService;

    @Autowired
    private KeyTranslationUploadRepository keyTranslationUploadRepository;

    @Autowired
    private SecureLoggingWriter secureLogger;

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

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

    /**
     * Upload key translation of current election event
     *
     * @param electionEventId
     * @param alias
     * @throws IOException
     */
    public void createUpdateElectionEventKeyTranslation(String electionEventId, String alias) {

        if (!keyTranslationUploadRepository.isAlreadyUploaded(electionEventId)) {
            ElectionEventTranslationList translations = new ElectionEventTranslationList();
            ElectionEventTranslation translation = new ElectionEventTranslation();
            translation.setAlias(alias);
            translation.setElectionEventId(electionEventId);
            translation.setTenantId(tenantId);
            translations.setElectionEventTranslations(Arrays.asList(translation));
            boolean result = keyTranslationUploadRepository.createUpdateElectionEventKeyTranslations(translations);

            if (result) {
                secureLogger.log(Level.INFO,
                    new LogContent.LogContentBuilder()
                        .logEvent(SdmSecureLogEvent.ELECTION_EVENT_KEY_TRANSLATION_UPLOADED_SUCCESSFULLY)
                        .additionalInfo("ee_id", electionEventId).createLogInfo());
            } else {
                secureLogger.log(Level.ERROR,
                    new LogContent.LogContentBuilder()
                        .logEvent(SdmSecureLogEvent.ELECTION_EVENT_KEY_TRANSLATION_UPLOADING_FAILED)
                        .additionalInfo("ee_id", electionEventId)
                        .additionalInfo("err_desc", "An error has ocurred while uploading Election Event translations")
                        .createLogInfo());
            }
        }
    }

    /**
     * Uploads a set of ballot box translations
     * 
     * @param electionEventId
     * @param translation
     * @return
     */
    public boolean createUpdateBallotBoxKeyTranslations(String electionEventId, BallotBoxTranslation translation) {

        BallotBoxTranslationList translationList = new BallotBoxTranslationList();
        translationList.addKeyTranslation(translation);
        boolean result;
        result = keyTranslationUploadRepository.createUpdateBallotBoxKeyTranslations(electionEventId, translationList);

        if (result) {
            secureLogger.log(Level.INFO,
                new LogContent.LogContentBuilder()
                    .logEvent(SdmSecureLogEvent.BALLOT_BOX_KEY_TRANSLATION_UPLOADED_SUCCESSFULLY)
                    .additionalInfo("bb_id", translation.getBallotBoxId()).createLogInfo());
        } else {
            secureLogger.log(Level.ERROR,
                new LogContent.LogContentBuilder()
                    .logEvent(SdmSecureLogEvent.BALLOT_BOX_KEY_TRANSLATION_UPLOADING_FAILED)
                    .additionalInfo("bb_id", translation.getBallotBoxId())
                    .additionalInfo("err_desc", "An error has ocurred while uploading Ballot Box translations")
                    .createLogInfo());
        }

        return result;
    }

    public void uploadElectionEventKeyTranslation(final String electionEventId) {

        if (!NULL_ELECTION_EVENT_ID.equals(electionEventId)) {
            uploadKeyTranslationForElectionEvent(electionEventId);
        } else {
            // Find all election events
            electionEventService.getAllElectionEventIds().forEach(this::uploadKeyTranslationForElectionEvent);
        }
    }

    private void uploadKeyTranslationForElectionEvent(final String electionEventId) {

        LOGGER.info("Updating the key translation of election event " + electionEventId);
        String electionEventAlias = electionEventService.getElectionEventAlias(electionEventId);
        createUpdateElectionEventKeyTranslation(electionEventId, electionEventAlias);
    }
}
