/*
 * 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.vw.services.infrastructure.remote;

import com.scytl.products.ov.commons.beans.domain.model.confirmation.TraceableConfirmationMessage;
import com.scytl.products.ov.commons.beans.domain.model.vote.Vote;
import com.scytl.products.ov.commons.beans.exceptions.ResourceNotFoundException;
import com.scytl.products.ov.commons.beans.validation.CryptographicOperationException;
import com.scytl.products.ov.commons.dto.CastCodeAndComputeResults;
import com.scytl.products.ov.commons.dto.ChoiceCodeAndComputeResults;
import com.scytl.products.ov.commons.dto.VoteAndComputeResults;
import com.scytl.products.ov.commons.ui.Constants;
import com.scytl.products.ov.vw.services.domain.model.verification.Verification;
import com.scytl.products.ov.vw.services.domain.model.verificationset.VerificationSet;

import retrofit2.Call;
import retrofit2.http.Body;
import retrofit2.http.GET;
import retrofit2.http.Header;
import retrofit2.http.POST;
import retrofit2.http.Path;

/**
 * The Interface for vote verification client.
 */
public interface VerificationClient {

    /** The Constant PARAMETER_VALUE_TENANT_ID. */
    public static final String PARAMETER_VALUE_TENANT_ID = "tenantId";

    /** The Constant PARAMETER_VALUE_ELECTION_EVENT_ID. */
    public static final String PARAMETER_VALUE_ELECTION_EVENT_ID = "electionEventId";

    /** The Constant PARAMETER_VERIFICATION_CARD_ID. */
    public static final String PARAMETER_VERIFICATION_CARD_ID = "verificationCardId";

    /** The Constant PARAMETER_VERIFICATION_CARD_SET_ID. */
    public static final String PARAMETER_VERIFICATION_CARD_SET_ID = "verificationCardSetId";

    /** The Constant PARAMETER_CHOICE_CODE_PATH. */
    public static final String PARAMETER_CHOICE_CODE_PATH = "choiceCodePath";

    /** The Constant PARAMETER_VERIFICATION_PATH. */
    public static final String PARAMETER_VERIFICATION_PATH = "verificationPath";

    /** The Constant PARAMETER_VERIFICATION_SET_PATH. */
    public static final String PARAMETER_VERIFICATION_SET_PATH = "verificationSetPath";

    /** The Constant PARAMETER_CAST_CODE_PATH. */
    public static final String PARAMETER_CAST_CODE_PATH = "castCodePath";

    /** The Constant PARAMETER_VALIDATION_PATH. */
    public static final String PARAMETER_VALIDATION_PATH = "validationPath";

    /**
     * Generate choice codes.
     *
     * @param trackId
     *            the track id for logging purposes
     * @param choiceCodePath
     *            the choice code path
     * @param tenantId
     *            the tenant id
     * @param electionEventId
     *            the election event id
     * @param verificationCardId
     *            the verification card id
     * @param vote
     *            the vote
     * @return the generated choice code with all compute results
     * @throws ResourceNotFoundException
     *             when the webservice fails
     */
    @POST("{choiceCodePath}/tenant/{tenantId}/electionevent/{electionEventId}/verificationcard/{verificationCardId}")
    Call<ChoiceCodeAndComputeResults> generateChoiceCodes(
            @Header(Constants.PARAMETER_HEADER_X_REQUEST_ID) String trackId,
            @Path(PARAMETER_CHOICE_CODE_PATH) String choiceCodePath, @Path(PARAMETER_VALUE_TENANT_ID) String tenantId,
            @Path(PARAMETER_VALUE_ELECTION_EVENT_ID) String electionEventId,
            @Path(PARAMETER_VERIFICATION_CARD_ID) String verificationCardId, @Body VoteAndComputeResults vote)
            throws ResourceNotFoundException;

    /**
     * Find verification by tenant, election event and verification card.
     *
     * @param trackId
     *            the track id for logging purposes
     * @param verificationPath
     *            the verification path
     * @param tenantId
     *            the tenant id
     * @param electionEventId
     *            the election event id
     * @param verificationCardId
     *            the verification card id
     * @return the verification data for the given parameters
     * @throws ResourceNotFoundException
     *             when the webservice fails
     */
    @GET("{verificationPath}/tenant/{tenantId}/electionevent/{electionEventId}/verificationcard/{verificationCardId}")
    Call<Verification> findVerificationByTenantElectionEventVerificationCard(
            @Header(Constants.PARAMETER_HEADER_X_REQUEST_ID) String trackId,
            @Path(PARAMETER_VERIFICATION_PATH) String verificationPath,
            @Path(PARAMETER_VALUE_TENANT_ID) String tenantId,
            @Path(PARAMETER_VALUE_ELECTION_EVENT_ID) String electionEventId,
            @Path(PARAMETER_VERIFICATION_CARD_ID) String verificationCardId) throws ResourceNotFoundException;

    /**
     * Find verification set by tenant, election event and verification card set
     * id.
     *
     * @param trackId
     *            the track id for logging purposes
     * @param verificationSetPath
     *            the verification set path
     * @param tenantId
     *            the tenant id
     * @param electionEventId
     *            the election event id
     * @param verificationCardSetId
     *            the verification card set id
     * @return the verification set data for the given parameters
     * @throws ResourceNotFoundException
     *             when the webservice fails
     */
    @GET("{verificationSetPath}/tenant/{tenantId}/electionevent/{electionEventId}/verificationcardset/{verificationCardSetId}")
    Call<VerificationSet> findVerificationSetByTenantElectionEventVerificationCardSetId(
            @Header(Constants.PARAMETER_HEADER_X_REQUEST_ID) String trackId,
            @Path(PARAMETER_VERIFICATION_SET_PATH) String verificationSetPath,
            @Path(PARAMETER_VALUE_TENANT_ID) String tenantId,
            @Path(PARAMETER_VALUE_ELECTION_EVENT_ID) String electionEventId,
            @Path(PARAMETER_VERIFICATION_CARD_SET_ID) String verificationCardSetId) throws ResourceNotFoundException;

    /**
     * Generate cast code.
     *
     * @param trackId
     *            the track id for logging purposes
     * @param castCodePath
     *            the cast code path
     * @param tenantId
     *            the tenant id
     * @param electionEventId
     *            the election event id
     * @param verificationCardId
     *            the verification card id
     * @param confirmationMessage
     *            the confirmation message
     * @return the vote cast message
     * @throws ResourceNotFoundException
     *             when the webservice fails
     */
    @POST("{castCodePath}/tenant/{tenantId}/electionevent/{electionEventId}/verificationcard/{verificationCardId}")
    Call<CastCodeAndComputeResults> generateCastCode(@Header(Constants.PARAMETER_HEADER_X_REQUEST_ID) String trackId,
            @Path(PARAMETER_CAST_CODE_PATH) String castCodePath, @Path(PARAMETER_VALUE_TENANT_ID) String tenantId,
            @Path(PARAMETER_VALUE_ELECTION_EVENT_ID) String electionEventId,
            @Path(PARAMETER_VERIFICATION_CARD_ID) String verificationCardId,
            @Body TraceableConfirmationMessage confirmationMessage) throws CryptographicOperationException;

    /**
     * Validate vote.
     *
     * @param trackId
     *            the track id for logging purposes
     * @param validationPath
     *            the validation path
     * @param tenantId
     *            the tenant id
     * @param electionEventId
     *            the election event id
     * @param vote
     *            the vote
     * @return the validation result
     * @throws ResourceNotFoundException
     *             when the webservice fails
     */
    @POST("{validationPath}/tenant/{tenantId}/electionevent/{electionEventId}")
    Call<com.scytl.products.ov.commons.validation.ValidationResult> validateVote(
            @Header(Constants.PARAMETER_HEADER_X_REQUEST_ID) String trackId,
            @Path(PARAMETER_VALIDATION_PATH) String validationPath, @Path(PARAMETER_VALUE_TENANT_ID) String tenantId,
            @Path(PARAMETER_VALUE_ELECTION_EVENT_ID) String electionEventId, @Body Vote vote)
            throws ResourceNotFoundException;
}
