/*
 * 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.tallying.webapp.mvc;

import com.scytl.products.oscore.logging.core.provider.TransactionInfoProvider;
import com.scytl.products.ov.tallying.api.TallyingService;
import com.scytl.products.ov.tallying.api.dto.output.TallyingOutput;
import com.scytl.products.ov.tallying.command.TallyingHolder;
import com.scytl.products.ov.tallying.commons.SignatureVerifier;
import com.scytl.products.ov.tallying.commons.exception.TallyingException;
import com.scytl.products.ov.tallying.webapp.mvc.dto.input.TallyingWebappInput;
import com.scytl.products.ov.tallying.webapp.mvc.dto.output.TallyingWebappOutput;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;

@Controller
public class TallyingEngineController {


    @Autowired
    private SignatureVerifier signatureVerifier;

    @Autowired
    private TallyingWebappAdapter tallyingWebappAdapter;

    @Autowired
    private TallyingService tallyingService;

    @Autowired
    private TransactionInfoProvider transactionInfoProvider;

    /**
     * REST Service for connectivity validation purposes
     */
    @RequestMapping(value = "/check", method = RequestMethod.GET)
    @ResponseBody
    public ResponseEntity<Void> serviceCheck() {
        return new ResponseEntity<>(HttpStatus.OK);
    }

    /**
     * REST Service for tallying
     */
    @RequestMapping(method = RequestMethod.POST)
    @ResponseBody
    public ResponseEntity<TallyingWebappOutput> tally(@RequestBody TallyingWebappInput input,
            final HttpServletRequest request) {

        try {

            transactionInfoProvider.generate(input.getTenantID(), request.getRemoteAddr(), request.getLocalAddr());
            TallyingHolder holder = tallyingWebappAdapter.adapt(input);

            TallyingOutput tallyingOutput = new TallyingOutput();

            boolean decryptedVotesFileIsCorrect =
                signatureVerifier.verifyDecryptedVotesFileSignature(holder, tallyingOutput);

            if (decryptedVotesFileIsCorrect) {
                tallyingService.tallyValidVotes(holder, tallyingOutput);
            }

            boolean invalidFilesAreCorrect =
                signatureVerifier.verifyAuditableVotesFileSignature(holder, tallyingOutput)
                    && signatureVerifier.verifyFailedVotesFileSignature(holder, tallyingOutput);

            if (invalidFilesAreCorrect) {
                tallyingService.tallyInvalidVotes(holder, tallyingOutput);
            }

            TallyingWebappOutput webappOutput = new TallyingWebappOutput();
            webappOutput.setErrors(tallyingOutput.getErrors());

            return new ResponseEntity<>(webappOutput, HttpStatus.OK);

        } catch (TallyingException ex) {

            return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
        }
    }

}
