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

import com.scytl.products.ov.sdm.application.service.IdleStatusService;
import com.scytl.products.ov.sdm.domain.common.IdleState;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import io.swagger.annotations.ApiResponse;
import io.swagger.annotations.ApiResponses;

import java.io.IOException;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import com.scytl.products.ov.commons.beans.exceptions.ApplicationException;
import com.scytl.products.ov.commons.beans.exceptions.ResourceNotFoundException;
import com.scytl.products.ov.sdm.application.service.CountingService;

/**
 * The counting endpoint.
 */
@RestController
@RequestMapping("/sdm-ws-rest/counting")
@Api(value = "Counting REST API", description = "")
public class CountingResource {

	private static final Logger LOGGER = LoggerFactory.getLogger(CountingResource.class);

	@Autowired
	CountingService countingService;

	@Autowired
	IdleStatusService idleStatusService;

	/**
	 * Performs the counting of certain ballot box.
	 *
	 * @param electionEventId the election event id.
	 * @param ballotBoxId the ballot box id.
	 * @return Status 200 on success.
	 * @throws InterruptedException
	 * @throws IOException
	 */
	@RequestMapping(value = "/electionevent/{electionEventId}/ballotbox/{ballotBoxId}", method = RequestMethod.POST, produces = "application/json")
	@ResponseBody
	@ApiOperation(value = "Count ballot box", notes = "Service to count a given ballot box.", response = String.class)
	@ApiResponses(value = {@ApiResponse(code = 404, message = "Not Found"), @ApiResponse(code = 403, message = "Forbidden"),
			@ApiResponse(code = 500, message = "Internal Server Error"),
			@ApiResponse(code = 501, message = "Not Implemented")})
	public ResponseEntity<IdleState> countBallotBox(
			@ApiParam(value = "String", required = true) @PathVariable String electionEventId,
			@ApiParam(value = "String", required = true) @PathVariable String ballotBoxId)
			throws IOException, ResourceNotFoundException {
	    if (!countingService.isEnabled()) {
	        return new ResponseEntity<>(HttpStatus.NOT_IMPLEMENTED);
	    }
	    
		//checks firstly if the ballot box id is already doing an operation
		IdleState idleState = new IdleState();
		if (!(idleStatusService.isIdReady(ballotBoxId))){
			idleState.setIdle(true);
			return new ResponseEntity<>(idleState,HttpStatus.OK);
		}
		try {
			if (countingService.countBallotBox(electionEventId, ballotBoxId)) {
				idleStatusService.freeIdleStatus(ballotBoxId);
				return new ResponseEntity<>(HttpStatus.OK);
			} else {
				idleStatusService.freeIdleStatus(ballotBoxId);
				return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
			}
		} catch (ResourceNotFoundException e) {
			idleStatusService.freeIdleStatus(ballotBoxId);
			LOGGER.error("A resource was missing when performing counting", e);
			return new ResponseEntity<>(HttpStatus.NOT_FOUND);
		} catch (ApplicationException e) {
			idleStatusService.freeIdleStatus(ballotBoxId);
			LOGGER.error("The request can not be performed for the current resource status", e);
			return new ResponseEntity<>(HttpStatus.FORBIDDEN);
		}
	}
	
	@RequestMapping(value = "/status", method = RequestMethod.GET, produces = "application/json")
    @ResponseBody
    @ApiOperation(value = "Counting is enabled", notes = "Returns the  counting status.", response = Boolean.class)
    @ApiResponses({@ApiResponse(code = 500, message = "Internal Server Error")})
    public ResponseEntity<CountingStatus> getStatus() {
        CountingStatus status = new CountingStatus();
        status.setEnabled(countingService.isEnabled());
        return new ResponseEntity<CountingStatus>(status, HttpStatus.OK);
    }
}
