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

import static java.util.Collections.singletonMap;

import java.util.ArrayList;
import java.util.List;

import javax.annotation.PostConstruct;
import javax.json.JsonArray;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

import com.orientechnologies.common.exception.OException;
import com.orientechnologies.orient.core.record.impl.ODocument;
import com.scytl.products.ov.commons.util.JsonUtils;
import com.scytl.products.ov.sdm.application.exception.DatabaseException;
import com.scytl.products.ov.sdm.domain.model.ballotbox.BallotBoxRepository;
import com.scytl.products.ov.sdm.domain.model.electoralauthority.ElectoralAuthority;
import com.scytl.products.ov.sdm.domain.model.electoralauthority.ElectoralAuthorityRepository;
import com.scytl.products.ov.sdm.infrastructure.AbstractEntityRepository;
import com.scytl.products.ov.sdm.infrastructure.DatabaseManager;
import com.scytl.products.ov.sdm.infrastructure.JsonConstants;

/**
 * Implementation of the interface which offers operations on the repository of
 * electoral repository.
 */
@Repository
public class ElectoralAuthorityRepositoryImpl extends
        AbstractEntityRepository implements ElectoralAuthorityRepository {

    @Autowired
    BallotBoxRepository ballotBoxRepository;

    /**
     * The constructor.
     *
     * @param databaseManager
     *            the injected database manager
     */
    @Autowired
    public ElectoralAuthorityRepositoryImpl(
            final DatabaseManager databaseManager) {
        super(databaseManager);
    }

    @PostConstruct
    @Override
    public void initialize() throws DatabaseException {
        super.initialize();
    }

    /**
     * @see com.scytl.products.ov.sdm.domain.model.electoralauthority.ElectoralAuthorityRepository#updateRelatedBallotBox(java.util.List)
     */
    @Override
    public void updateRelatedBallotBox(
            final List<String> electoralAuthoritiesIds) {
        try {
            for (String id : electoralAuthoritiesIds) {
                ODocument authority = getDocument(id);
                List<String> aliases = getBallotBoxAliases(id);
                authority.field(
                    JsonConstants.JSON_ATTRIBUTE_NAME_BALLOT_BOX_ALIAS,
                    aliases);
                saveDocument(authority);
            }
        } catch (OException e) {
            throw new DatabaseException(
                "Failed to update related ballot box.", e);
        }
    }

    @Override
    public String listByElectionEvent(final String electionEventId)
            throws DatabaseException {
        return list(singletonMap("electionEvent.id", electionEventId));
    }

    @Override
    protected String entityName() {
        return ElectoralAuthority.class.getSimpleName();
    }

    // Return the aliases of all the ballot boxes for the electoral authority
    // identified by electoralAuthorityId.
    private List<String> getBallotBoxAliases(
            final String electoralAuthorityId) {
        JsonArray ballotBoxesResult = JsonUtils
            .getJsonObject(ballotBoxRepository
                .findByElectoralAuthority(electoralAuthorityId))
            .getJsonArray(JsonConstants.JSON_ATTRIBUTE_NAME_RESULT);
        List<String> ballotBoxIds = new ArrayList<>();
        for (int index = 0; index < ballotBoxesResult.size(); index++) {
            ballotBoxIds.add(ballotBoxesResult.getJsonObject(index)
                .getString(JsonConstants.JSON_ATTRIBUTE_NAME_ALIAS));
        }

        return ballotBoxIds;
    }
}
