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

import com.google.gson.Gson;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.ejb.Stateless;
import javax.inject.Inject;
import javax.servlet.http.HttpServletRequest;
import javax.validation.constraints.NotNull;
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.HeaderParam;
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 java.io.IOException;

import com.scytl.products.oscore.logging.core.provider.TransactionInfoProvider;
import com.scytl.products.ov.au.services.domain.model.authentication.ElectionEventData;
import com.scytl.products.ov.au.services.domain.service.ElectionEventService;
import com.scytl.products.ov.au.services.domain.service.exception.ElectionEventException;
import com.scytl.products.ov.commons.beans.exceptions.ApplicationException;
import com.scytl.products.ov.commons.beans.exceptions.DuplicateEntryException;
import com.scytl.products.ov.commons.tracking.TrackIdInstance;
import com.scytl.products.ov.commons.ui.Constants;
import com.scytl.products.ov.commons.util.HttpRequestService;
import com.scytl.products.ov.commons.validation.ValidationResult;

/**
 * Web service for handling electoral data resource.
 */
@Path("/electioneventdata")
@Stateless(name = "au-ElectionEventDataResource")
public class ElectionEventDataResource {

    public static final String ADMINISTRATION_BOARD_CN_PREFIX = "AdministrationBoard ";

    // 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";

    private static final String QUERY_PARAMETER_ADMIN_BOARD_ID = "adminBoardId";

    private static final Logger LOG = LoggerFactory.getLogger("std");

    @Inject
    private TransactionInfoProvider transactionInfoProvider;

    @Inject
    private HttpRequestService httpRequestService;

    // The track id instance
    @Inject
    private TrackIdInstance trackIdInstance;

    @Inject
    private ElectionEventService electionEventService;

    /**
     * Save the election event data given the tenant and the election event id.
     *
     * @param tenantId        - the tenant identifier.
     * @param electionEventId - the election event identifier.
     * @param request         - the http servlet request.
     * @return status 200 on success.
     * @throws ApplicationException    if the input parameters are not valid.
     * @throws DuplicateEntryException if the entry already exists
     */
    @POST
    @Path("tenant/{tenantId}/electionevent/{electionEventId}/adminboard/{adminBoardId}")
    @Consumes(MediaType.APPLICATION_JSON)
    public Response saveElectionEventData(@HeaderParam(Constants.PARAMETER_HEADER_X_REQUEST_ID) String trackingId,
                                          @PathParam(QUERY_PARAMETER_TENANT_ID) String tenantId,
                                          @PathParam(QUERY_PARAMETER_ELECTION_EVENT_ID) String electionEventId,
                                          @PathParam(QUERY_PARAMETER_ADMIN_BOARD_ID) String adminBoardId,
                                          @NotNull ElectionEventData electionEventData,
                                          @Context HttpServletRequest request)
        throws ApplicationException, DuplicateEntryException, IOException {

        trackIdInstance.setTrackId(trackingId);

        transactionInfoProvider.generate(tenantId, httpRequestService.getIpClientAddress(request),
            httpRequestService.getIpServer(request));
        try {
            electionEventService.saveElectionEventData(tenantId, electionEventId, adminBoardId, electionEventData);
            return Response.ok().build();
        } catch (ElectionEventException e) {
            LOG.error("Error while saving election information", e);
            return Response.status(Response.Status.PRECONDITION_FAILED).build();
        }
    }

    /**
     * Returns the result of validate if the election event data is empty.
     *
     * @param tenantId        - the tenant identifier.
     * @param electionEventId - the election event identifier.
     * @return Returns the result of the validation.
     */
    @GET
    @Produces(MediaType.APPLICATION_JSON)
    @Path("tenant/{tenantId}/electionevent/{electionEventId}/status")
    public Response checkIfElectionEventDataIsEmpty(@HeaderParam(Constants.PARAMETER_HEADER_X_REQUEST_ID) String trackingId,
                                                    @PathParam(QUERY_PARAMETER_TENANT_ID) String tenantId,
                                                    @PathParam(QUERY_PARAMETER_ELECTION_EVENT_ID) String electionEventId,
                                                    @Context HttpServletRequest request) {

        trackIdInstance.setTrackId(trackingId);

        ValidationResult validationResult = electionEventService.checkIfElectionEventDataIsEmpty(tenantId, electionEventId);
        
        Gson gson = new Gson();
        // convert to string
        String json = gson.toJson(validationResult);

        return Response.ok().entity(json).build();
    }
}
