/*
 * 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.ui.ws.rs.operation.admin;

import okhttp3.RequestBody;
import okhttp3.ResponseBody;

import javax.ejb.Stateless;
import javax.ejb.TransactionAttribute;
import javax.ejb.TransactionAttributeType;
import javax.inject.Inject;
import javax.servlet.http.HttpServletRequest;
import javax.validation.constraints.NotNull;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.InputStream;

import com.scytl.products.ov.ag.services.infrastructure.remote.admin.ElectionInformationAdminClient;
import com.scytl.products.ov.ag.ui.ws.rs.proxy.XForwardedForFactory;
import com.scytl.products.ov.ag.ui.ws.rs.proxy.XForwardedForFactoryImpl;
import com.scytl.products.ov.commons.infrastructure.remote.client.InputStreamTypedOutput;
import com.scytl.products.ov.commons.infrastructure.remote.client.RetrofitConsumer;
import com.scytl.products.ov.commons.infrastructure.remote.client.RetrofitException;
import com.scytl.products.ov.commons.tracking.TrackIdGenerator;
import com.scytl.products.ov.commons.util.PropertiesFileReader;

/**
 * Web service for handling ballot box data information.
 */
@Stateless(name = "ag-BallotBoxDataResource")
@TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
@Path(BallotBoxDataResource.RESOURCE_PATH)
public class BallotBoxDataResource {

    static final String ADD_BALLOT_BOX_CONTENT_AND_INFORMATION =
        "tenant/{tenantId}/electionevent/{electionEventId}/ballotbox/{ballotBoxId}/adminboard/{adminBoardId}";

    static final String RESOURCE_PATH = "/ei/ballotboxdata";

    // The name of the query parameter tenantId
    private static final String QUERY_PARAMETER_TENANT_ID = "tenantId";

    // The name of the query parameter electionEventId
    private static final String QUERY_PARAMETER_ELECTION_EVENT_ID = "electionEventId";

    // The name of the query parameter ballotBoxId
    private static final String QUERY_PARAMETER_BALLOT_BOX_ID = "ballotBoxId";

    private static final String QUERY_PARAMETER_ADMIN_BOARD_ID = "adminBoardId";

    // The properties file reader.
    private static final PropertiesFileReader PROPERTIES = PropertiesFileReader.getInstance();

    // The path to the resource ballot box data.
    static final String BALLOT_BOX_DATA_PATH = PROPERTIES.getPropertyValue("BALLOT_BOX_DATA_PATH");

    private final XForwardedForFactory xForwardedForFactory = XForwardedForFactoryImpl.getInstance();

    private ElectionInformationAdminClient electionInformationAdminClient;

    private TrackIdGenerator trackIdGenerator;
    
    private static final Logger LOG = LoggerFactory.getLogger(BallotBoxDataResource.class);
    
    @Inject
    BallotBoxDataResource(ElectionInformationAdminClient electionInformationAdminClient,
                          TrackIdGenerator trackIdGenerator) {
        this.electionInformationAdminClient = electionInformationAdminClient;
        this.trackIdGenerator = trackIdGenerator;
    }

    @POST
    @Produces(MediaType.APPLICATION_JSON)
    @Path(ADD_BALLOT_BOX_CONTENT_AND_INFORMATION)
    public Response addBallotBoxContentAndInformation(@PathParam(QUERY_PARAMETER_TENANT_ID) final String tenantId,
            @PathParam(QUERY_PARAMETER_ELECTION_EVENT_ID) final String electionEventId,
            @PathParam(QUERY_PARAMETER_BALLOT_BOX_ID) final String ballotBoxId,
            @PathParam(QUERY_PARAMETER_ADMIN_BOARD_ID) final String adminBoardId,
            @NotNull final InputStream info,
            @Context final HttpServletRequest request) {
        String xForwardedFor = xForwardedForFactory.newXForwardedFor(request);
        final String trackingId = trackIdGenerator.generate();

        RequestBody body =
                new InputStreamTypedOutput(MediaType.APPLICATION_JSON, info);

		try (ResponseBody responseBody = RetrofitConsumer
				.processResponse(electionInformationAdminClient.addBallotBoxContentAndInformation(BALLOT_BOX_DATA_PATH,
						tenantId, electionEventId, ballotBoxId, adminBoardId, xForwardedFor, trackingId, body))) {
			return Response.ok().build();
		} catch (RetrofitException rfE) {
			LOG.error("Error trying to process ballot boxes.", rfE);
			return Response.status(rfE.getHttpCode()).build();
		}
    }
}
