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

import javax.validation.constraints.NotNull;

import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import com.scytl.products.ov.commons.infrastructure.remote.client.RestClientInterceptor;

import javax.ws.rs.core.MediaType;
import okhttp3.RequestBody;
import okhttp3.ResponseBody;
import retrofit2.Call;
import retrofit2.http.Body;
import retrofit2.http.GET;
import retrofit2.http.Header;
import retrofit2.http.Headers;
import retrofit2.http.POST;
import retrofit2.http.Path;
import retrofit2.http.Query;
import retrofit2.http.Streaming;

public interface OrchestratorClient {

    String PARAMETER_VALUE_TENANT_ID = "tenantId";

    String PARAMETER_VALUE_ELECTION_EVENT_ID = "electionEventId";

    String PARAMETER_VALUE_VERIFICATION_CARD_SET_ID = "verificationCardSetId";    

    String PARAMETER_X_FORWARDED_FOR = "X-Forwarded-For";

    String PARAMETER_X_REQUEST_ID = "X-Request-ID";

    String PARAMETER_PATH_COMPUTE_CHOICE_CODES = "pathComputeChoiceCodes";

    String PARAMETER_PATH_COMPUTE_CHOICE_CODES_REQUEST = "pathComputeChoiceCodesRequest";

    String PARAMETER_PATH_COMPUTE_CHOICE_CODES_RETRIEVAL = "pathComputeChoiceCodesRetrieval";

    String PARAMETER_PATH_GENERATE_MIXDEC_KEYS = "pathGenerateMixDecKeys";

    String PARAMETER_PATH_GENERATE_CHOICE_CODES_KEYS = "pathGenerateChoiceCodesKeys";

    String PARAMETER_PATH_MIX_DECRYPT = "pathMixDecrypt";

    String PARAMETER_VALUE_BALLOT_BOX_ID = "ballotBoxId";
    
    String PARAMETER_VALUE_CHUNK_ID = "chunkId";
    
    String PARAMETER_VALUE_CHUNK_COUNT = "chunkCount";

    @POST("{pathComputeChoiceCodesRequest}/computeGenerationContributions")
    Call<ResponseBody> requestComputeChoiceCodes(@Path(PARAMETER_PATH_COMPUTE_CHOICE_CODES_REQUEST) String pathComputeChoiceCodes,
            @NotNull @Header(PARAMETER_X_FORWARDED_FOR) String xForwardedFor,
            @NotNull @Header(PARAMETER_X_REQUEST_ID) String trackingId,
            @NotNull @Body RequestBody computeInputJsonString);

    @GET("{pathComputeChoiceCodesRetrieval}/tenant/{tenantId}/electionevent/{electionEventId}/verificationCardSetId/{verificationCardSetId}/chunkId/{chunkId}/computeGenerationContributions")
    Call<ResponseBody> retrieveComputedChoiceCodes(@Path(PARAMETER_PATH_COMPUTE_CHOICE_CODES_RETRIEVAL) String pathComputeChoiceCodes,
            @Path(PARAMETER_VALUE_TENANT_ID) String tenantId,
            @Path(PARAMETER_VALUE_ELECTION_EVENT_ID) String electionEventId,
            @Path(PARAMETER_VALUE_VERIFICATION_CARD_SET_ID) String verificationCardSetId,
            @Path(PARAMETER_VALUE_CHUNK_ID) int chunkId,
            @NotNull @Header(PARAMETER_X_FORWARDED_FOR) String xForwardedFor,
            @NotNull @Header(PARAMETER_X_REQUEST_ID) String trackingId);

    @POST("{pathGenerateMixDecKeys}/tenant/{tenantId}/electionevent/{electionEventId}/keys")
    Call<JsonObject> generateMixDecKeys(@Path(PARAMETER_PATH_GENERATE_MIXDEC_KEYS) String pathGenerateMixDecKeys,
            @Path(PARAMETER_VALUE_TENANT_ID) String tenantId,
            @Path(PARAMETER_VALUE_ELECTION_EVENT_ID) String electionEventId,
            @NotNull @Body RequestBody electoralAuthorityIds,
            @NotNull @Header(RestClientInterceptor.HEADER_ORIGINATOR) String originator,
            @NotNull @Header(RestClientInterceptor.HEADER_SIGNATURE) String signature,
            @NotNull @Header(PARAMETER_X_FORWARDED_FOR) String xForwardedFor,
            @NotNull @Header(PARAMETER_X_REQUEST_ID) String trackingId);

    @POST("{pathGenerateChoiceCodesKeys}/tenant/{tenantId}/electionevent/{electionEventId}/keys")
    Call<JsonObject> generateChoiceCodesKeys(
            @Path(PARAMETER_PATH_GENERATE_CHOICE_CODES_KEYS) String pathGenerateChoiceCodesKeys,
            @Path(PARAMETER_VALUE_TENANT_ID) String tenantId,
            @Path(PARAMETER_VALUE_ELECTION_EVENT_ID) String electionEventId,
            @NotNull @Body RequestBody votingCardSetIds,
            @NotNull @Header(RestClientInterceptor.HEADER_ORIGINATOR) String originator,
            @NotNull @Header(RestClientInterceptor.HEADER_SIGNATURE) String signature,
            @NotNull @Header(PARAMETER_X_FORWARDED_FOR) String xForwardedFor,
            @NotNull @Header(PARAMETER_X_REQUEST_ID) String trackingId);

    @POST("{pathMixDecrypt}/secured/tenant/{tenantId}/electionevent/{electionEventId}/ballotboxes")
    Call<JsonArray> processBallotBoxes(
            @Path(PARAMETER_PATH_MIX_DECRYPT) String pathMixDecrypt,
            @Path(PARAMETER_VALUE_TENANT_ID) String tenantId,
            @Path(PARAMETER_VALUE_ELECTION_EVENT_ID) String electionEventId,
            @NotNull @Body RequestBody ballotBoxIds,
            @NotNull @Header(RestClientInterceptor.HEADER_ORIGINATOR) String originator,
            @NotNull @Header(RestClientInterceptor.HEADER_SIGNATURE) String signature,
            @NotNull @Header(PARAMETER_X_FORWARDED_FOR) String xForwardedFor,
            @NotNull @Header(PARAMETER_X_REQUEST_ID) String trackingId);

    /**
     * @deprecated (SV-5291)
     */
    @GET("{pathMixDecrypt}/secured/tenant/{tenantId}/electionevent/{electionEventId}/ballotbox/{ballotBoxId}")
    @Headers("Accept:" + MediaType.APPLICATION_OCTET_STREAM)
    @Streaming
    @Deprecated // SV-5291
    Call<ResponseBody> getProcessedBallotBox(@Path(PARAMETER_PATH_MIX_DECRYPT) String pathMixDecrypt,
            @Path(PARAMETER_VALUE_TENANT_ID) String tenantId,
            @Path(PARAMETER_VALUE_ELECTION_EVENT_ID) String electionEventId,
            @Path(PARAMETER_VALUE_BALLOT_BOX_ID) String ballotBoxId,
            @NotNull @Header(RestClientInterceptor.HEADER_ORIGINATOR) String originator,
            @NotNull @Header(RestClientInterceptor.HEADER_SIGNATURE) String signature,
            @NotNull @Header(PARAMETER_X_FORWARDED_FOR) String xForwardedFor,
            @NotNull @Header(PARAMETER_X_REQUEST_ID) String trackingId);

    @GET("{pathMixDecrypt}/secured/tenant/{tenantId}/electionevent/{electionEventId}/ballotbox/{ballotBoxId}/nodeoutputs")
    @Headers("Accept:" + MediaType.APPLICATION_OCTET_STREAM)
    @Streaming
    Call<ResponseBody> getMixDecNodeOutputs(@Path(PARAMETER_PATH_MIX_DECRYPT) String pathMixDecrypt,
            @Path(PARAMETER_VALUE_TENANT_ID) String tenantId,
            @Path(PARAMETER_VALUE_ELECTION_EVENT_ID) String electionEventId,
            @Path(PARAMETER_VALUE_BALLOT_BOX_ID) String ballotBoxId,
            @NotNull @Header(RestClientInterceptor.HEADER_ORIGINATOR) String originator,
            @NotNull @Header(RestClientInterceptor.HEADER_SIGNATURE) String signature,
            @NotNull @Header(PARAMETER_X_FORWARDED_FOR) String xForwardedFor,
            @NotNull @Header(PARAMETER_X_REQUEST_ID) String trackingId);

    @GET("{pathMixDecrypt}/secured/tenant/{tenantId}/electionevent/{electionEventId}/ballotbox/{ballotBoxId}/status")
    @Headers("Accept:" + MediaType.APPLICATION_JSON)
    Call<JsonObject> getBallotBoxStatus(
            @Path(PARAMETER_PATH_MIX_DECRYPT) String pathMixDecrypt,
            @Path(PARAMETER_VALUE_TENANT_ID) String tenantId,
            @Path(PARAMETER_VALUE_ELECTION_EVENT_ID) String electionEventId,
            @Path(PARAMETER_VALUE_BALLOT_BOX_ID) String ballotBoxId,
            @NotNull @Header(RestClientInterceptor.HEADER_ORIGINATOR) String originator,
            @NotNull @Header(RestClientInterceptor.HEADER_SIGNATURE) String signature,
            @NotNull @Header(PARAMETER_X_FORWARDED_FOR) String xForwardedFor,
            @NotNull @Header(PARAMETER_X_REQUEST_ID) String trackingId);

    @GET("{pathComputeChoiceCodes}/tenant/{tenantId}/electionevent/{electionEventId}/verificationCardSetId/{verificationCardSetId}/generationContributions/status")
    Call<JsonObject> getChoiceCodesComputationStatus(@Path(PARAMETER_PATH_COMPUTE_CHOICE_CODES) String pathComputeChoiceCodes,
                                                     @Path(PARAMETER_VALUE_TENANT_ID) String tenantId,
                                                     @Path(PARAMETER_VALUE_ELECTION_EVENT_ID) String electionEventId,
                                                     @Path(PARAMETER_VALUE_VERIFICATION_CARD_SET_ID) String verificationCardSetId,
                                                     @Query(PARAMETER_VALUE_CHUNK_COUNT) int chunkCount,
                                                     @NotNull @Header(PARAMETER_X_FORWARDED_FOR) String xForwardedFor,
                                                     @NotNull @Header(PARAMETER_X_REQUEST_ID) String trackingId);
}
