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

import com.google.gson.JsonObject;

import retrofit2.Call;
import okhttp3.ResponseBody;
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.Streaming;
import okhttp3.RequestBody;

import javax.validation.constraints.NotNull;
import javax.ws.rs.core.MediaType;

import com.scytl.products.ov.commons.infrastructure.remote.client.RestClientInterceptor;

/**
 * The Interface of election information client for admin.
 */
public interface ElectionInformationAdminClient {

    /** The Constant PARAMETER_VALUE_TENANT_ID. */
    String PARAMETER_VALUE_TENANT_ID = "tenantId";

    /** The Constant PARAMETER_VALUE_ELECTION_EVENT_ID. */
    String PARAMETER_VALUE_ELECTION_EVENT_ID = "electionEventId";

    /** The Constant PARAMETER_VALUE_VOTING_CARD_ID. */
    String PARAMETER_VALUE_VOTING_CARD_ID = "votingCardId";

    /** The Constant PARAMETER_VALUE_BALLOT_BOX_ID. */
    String PARAMETER_VALUE_BALLOT_BOX_ID = "ballotBoxId";

    /** The Constant PARAMETER_VALUE_BALLOT_ID. */
    String PARAMETER_VALUE_BALLOT_ID = "ballotId";

    /** The Constant PARAMETER_VALUE_ADMIN_BOARD_ID. */
    String PARAMETER_VALUE_ADMIN_BOARD_ID = "adminBoardId";

    /** The Constant PARAMETER_VALUE_ELECTORAL_AUTHORITY_ID. */
    String PARAMETER_VALUE_ELECTORAL_AUTHORITY_ID = "electoralAuthorityId";

    /** The Constant PARAMETER_PATH_BALLOTBOXES. */
    String PARAMETER_PATH_BALLOTBOXES = "pathBallotboxes";

    /** The Constant PARAMETER_PATH_BALLOTBOXDATA. */
    String PARAMETER_PATH_BALLOTBOXDATA = "pathBallotboxdata";

    /** The Constant PARAMETER_PATH_BALLOTDATA. */
    String PARAMETER_PATH_BALLOTDATA = "pathBallotdata";

    /** The Constant PARAMETER_PATH_BALLOTDATA. */
    String PARAMETER_PATH_ELECTORALDATA = "pathElectoraldata";

    /** The Constant PARAMETER_PATH_BALLOTDATA. */
    String PARAMETER_PATH_ELECTIONEVENTDATA = "pathElectioneventdata";

    /** The Constant PARAMETER_PATH_BALLOTBOXSTATUS. */
    String PARAMETER_PATH_BALLOTBOXSTATUS = "pathBallotboxstatus";

    /** The Constant PARAMETER_AUTHENTICATION_TOKEN. */
    String PARAMETER_AUTHENTICATION_TOKEN = "authenticationToken";

    /** The Constant PARAMETER_TENANT_DATA_PATH. */
    String PARAMETER_PATH_TENANT_DATA = "pathTenantData";

    /** The Constant X_FORWARDED_FOR. */
    String PARAMETER_X_FORWARDED_FOR = "X-Forwarded-For";

    /** The Constant X_REQUEST_ID. */
    String PARAMETER_X_REQUEST_ID = "X-Request-ID";

    /** The Constant CLEANSING_OUTPUTS */
    String PARAMETER_PATH_CLEANSING_OUTPUTS = "pathCleansingOutputs";

    @GET("{pathBallotboxes}/secured/tenant/{tenantId}/electionevent/{electionEventId}/ballotbox/{ballotBoxId}")
    @Headers("Accept: text/csv")
    Call<ResponseBody> getEncryptedBallotBoxAsString(@Path(PARAMETER_PATH_BALLOTBOXES) String pathBallotboxes,
            @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(PARAMETER_X_FORWARDED_FOR) String xForwardedFor,
            @NotNull @Header(PARAMETER_X_REQUEST_ID) String trackingId,
            @NotNull @Header(RestClientInterceptor.HEADER_ORIGINATOR) String originator,
            @NotNull @Header(RestClientInterceptor.HEADER_SIGNATURE) String signature);

    @GET("{pathBallotboxes}/secured/tenant/{tenantId}/electionevent/{electionEventId}/ballotbox/{ballotBoxId}")
    @Headers("Accept:" + MediaType.APPLICATION_OCTET_STREAM)
    @Streaming
    Call<ResponseBody> getEncryptedBallotBox(@Path(PARAMETER_PATH_BALLOTBOXES) String pathBallotboxes,
            @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(PARAMETER_X_FORWARDED_FOR) String xForwardedFor,
            @NotNull @Header(PARAMETER_X_REQUEST_ID) String trackingId,
            @NotNull @Header(RestClientInterceptor.HEADER_ORIGINATOR) String originator,
            @NotNull @Header(RestClientInterceptor.HEADER_SIGNATURE) String signature);

    @POST("{pathBallotdata}/tenant/{tenantId}/electionevent/{electionEventId}/ballot/{ballotId}/adminboard/{adminBoardId}")
    Call<ResponseBody> saveBallotData(@Path(PARAMETER_PATH_BALLOTDATA) String pathBallotdata,
            @Path(PARAMETER_VALUE_TENANT_ID) String tenantId,
            @Path(PARAMETER_VALUE_ELECTION_EVENT_ID) String electionEventId,
            @Path(PARAMETER_VALUE_BALLOT_ID) String ballotId, @Path(PARAMETER_VALUE_ADMIN_BOARD_ID) String adminBoardId,
            @NotNull @Header(PARAMETER_X_FORWARDED_FOR) String xForwardedFor,
            @NotNull @Header(PARAMETER_X_REQUEST_ID) String trackingId, @NotNull @Body RequestBody ballotData);

    @POST("{pathBallotboxdata}/tenant/{tenantId}/electionevent/{electionEventId}/ballotbox/{ballotBoxId}/adminboard/{adminBoardId}")
    Call<ResponseBody> addBallotBoxContentAndInformation(@Path(PARAMETER_PATH_BALLOTBOXDATA) String pathBallotboxdata,
            @Path(PARAMETER_VALUE_TENANT_ID) String tenantId,
            @Path(PARAMETER_VALUE_ELECTION_EVENT_ID) String electionEventId,
            @Path(PARAMETER_VALUE_BALLOT_BOX_ID) String ballotBoxId,
            @Path(PARAMETER_VALUE_ADMIN_BOARD_ID) String adminBoardId,
            @NotNull @Header(PARAMETER_X_FORWARDED_FOR) String xForwardedFor,
            @NotNull @Header(PARAMETER_X_REQUEST_ID) String trackingId, @NotNull @Body RequestBody ballotBoxData);

    @POST("{pathElectoraldata}/tenant/{tenantId}/electionevent/{electionEventId}/electoralauthority/{electoralAuthorityId}/adminboard/{adminBoardId}")
    Call<ResponseBody> saveElectoralData(@Path(PARAMETER_PATH_ELECTORALDATA) String pathElectoraldata,
            @Path(PARAMETER_VALUE_TENANT_ID) String tenantId,
            @Path(PARAMETER_VALUE_ELECTION_EVENT_ID) String electionEventId,
            @Path(PARAMETER_VALUE_ELECTORAL_AUTHORITY_ID) String electoralAuthorityId,
            @Path(PARAMETER_VALUE_ADMIN_BOARD_ID) String adminBoardId,
            @NotNull @Header(PARAMETER_X_FORWARDED_FOR) String xForwardedFor,
            @NotNull @Header(PARAMETER_X_REQUEST_ID) String trackingId, @NotNull @Body RequestBody electoralData);

    @POST("{pathElectioneventdata}/tenant/{tenantId}/electionevent/{electionEventId}/adminboard/{adminBoardId}")
    Call<ResponseBody> saveElectionEventData(@Path(PARAMETER_PATH_ELECTIONEVENTDATA) String pathElectioneventdata,
            @Path(PARAMETER_VALUE_TENANT_ID) String tenantId,
            @Path(PARAMETER_VALUE_ELECTION_EVENT_ID) String electionEventId,
            @Path(PARAMETER_VALUE_ADMIN_BOARD_ID) String adminBoardId,
            @NotNull @Header(PARAMETER_X_FORWARDED_FOR) String xForwardedFor,
            @NotNull @Header(PARAMETER_X_REQUEST_ID) String trackingId, @NotNull @Body RequestBody electioneventData);

    @GET("{pathBallotboxstatus}/tenant/{tenantId}/electionevent/{electionEventId}/ballotbox/{ballotBoxId}/status")
    Call<JsonObject> checkIfBallotBoxIsEmpty(@Path(PARAMETER_PATH_BALLOTBOXSTATUS) String pathBallotboxstatus,
            @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(PARAMETER_X_FORWARDED_FOR) String xForwardedFor,
            @NotNull @Header(PARAMETER_X_REQUEST_ID) String trackingId);

    @GET("{pathBallotboxstatus}/tenant/{tenantId}/electionevent/{electionEventId}/ballotbox/{ballotBoxId}/available")
    Call<JsonObject> checkIfBallotBoxIsAvailable(@Path(PARAMETER_PATH_BALLOTBOXSTATUS) String pathBallotboxstatus,
            @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(PARAMETER_X_FORWARDED_FOR) String xForwardedFor,
            @NotNull @Header(PARAMETER_X_REQUEST_ID) String trackingId);

    @GET("{pathElectioneventdata}/tenant/{tenantId}/electionevent/{electionEventId}/status")
    Call<JsonObject> checkIfElectionEventDataIsEmpty(@Path(PARAMETER_PATH_ELECTIONEVENTDATA) String pathElectioneventdata,
            @Path(PARAMETER_VALUE_TENANT_ID) String tenantId,
            @Path(PARAMETER_VALUE_ELECTION_EVENT_ID) String electionEventId,
            @NotNull @Header(PARAMETER_X_FORWARDED_FOR) String xForwardedFor,
            @NotNull @Header(PARAMETER_X_REQUEST_ID) String trackingId);

    @GET("{pathElectioneventdata}/secured/tenant/{tenantId}/electionevent/{electionEventId}/used-voting-cards")
    @Streaming
    Call<ResponseBody> getCastedVotingCardsReport(@Path(PARAMETER_PATH_ELECTIONEVENTDATA) String pathElectioneventdata,
            @Path(PARAMETER_VALUE_TENANT_ID) String tenantId,
            @Path(PARAMETER_VALUE_ELECTION_EVENT_ID) String electionEventId,
            @NotNull @Header(PARAMETER_X_FORWARDED_FOR) String xForwardedFor,
            @NotNull @Header(PARAMETER_X_REQUEST_ID) String trackingId,
            @NotNull @Header(RestClientInterceptor.HEADER_ORIGINATOR) String originator,
            @NotNull @Header(RestClientInterceptor.HEADER_SIGNATURE) String signature);

    @GET("{pathTenantData}/activatetenant/tenant/{tenantId}")
    Call<JsonObject> checkTenantActivation(@Path(PARAMETER_PATH_TENANT_DATA) String pathTenantData,
            @Path(PARAMETER_VALUE_TENANT_ID) String tenantId,
            @NotNull @Header(PARAMETER_X_FORWARDED_FOR) String xForwardedFor,
            @NotNull @Header(PARAMETER_X_REQUEST_ID) String trackingId);

    @POST("{pathBallotboxes}/secured/tenant/{tenantId}/electionevent/{electionEventId}/block")
    Call<ResponseBody> blockBallotBoxes(@Path(PARAMETER_PATH_BALLOTBOXES) String pathBallotboxes,
            @Path(PARAMETER_VALUE_TENANT_ID) String tenantId,
            @Path(PARAMETER_VALUE_ELECTION_EVENT_ID) String electionEventId, @NotNull @Body RequestBody ballotBoxes,
            @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("{pathBallotboxes}/secured/tenant/{tenantId}/electionevent/{electionEventId}/unblock")
    Call<ResponseBody> unblockBallotBoxes(@Path(PARAMETER_PATH_BALLOTBOXES) String pathBallotboxes,
            @Path(PARAMETER_VALUE_TENANT_ID) String tenantId,
            @Path(PARAMETER_VALUE_ELECTION_EVENT_ID) String electionEventId, @NotNull @Body RequestBody ballotBoxes,
            @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("{pathCleansingOutputs}/secured/tenant/{tenantId}/electionevent/{electionEventId}/ballotbox/{ballotBoxId}/successfulvotes")
    @Headers("Accept:" + MediaType.APPLICATION_OCTET_STREAM)
    @Streaming
    Call<ResponseBody> getSuccessfulVotes(@Path(PARAMETER_PATH_CLEANSING_OUTPUTS) String pathCleansingOutputs,
                                          @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("{pathCleansingOutputs}/secured/tenant/{tenantId}/electionevent/{electionEventId}/ballotbox/{ballotBoxId}/failedvotes")
    @Headers("Accept:" + MediaType.APPLICATION_OCTET_STREAM)
    @Streaming
    Call<ResponseBody> getFailedVotes(@Path(PARAMETER_PATH_CLEANSING_OUTPUTS) String pathCleansingOutputs,
                                          @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);
}
