package meerkat.pollingstation;

import com.google.common.util.concurrent.FutureCallback;
import com.google.protobuf.BoolValue;
import meerkat.protobuf.Crypto;
import meerkat.protobuf.PollingStation.*;

import java.util.concurrent.Future;

/**
 * Created by Arbel on 05/05/2016.
 * An interface for the scanner used by the Polling Station Committee
 * The scanner works as a producer, while the polling station is the consumer
 * That is to say: scans are pushed from the scanner rather than requested by the polling station
 */
public interface PollingStationScanner {

    /**
     * An interface for processing scans (Polling Station side)
     */
    public interface PollingStationServer {

        /**
         * Sets up the connection to the scanner and begins receiving scans.
         * Returns the data the scanner client will need to connect
         * If verifyScanner is true, will verify that scanner has the correct nonce before
         * allowing connection, and verify signatures on scanned data.
         * @throws Exception when the operation fails
         */
        public ConnectionServerData start(boolean verifyScanner) throws Exception;

        /**
         * Closes the connection to the scanner
         * @throws Exception when the operation fails
         */
        public void stop() throws Exception;

        /**
         * Subscribes to new scans
         *
         * @param scanCallback is the handler for scanned data
         */
        public void subscribe(FutureCallback<ScannedData> scanCallback);
    }


    /**
     * An interface for handling the WebAPI (on the polling-station side)
     */
    public interface PollingStationWebAPI {

        /**
         * Connect to the polling station server.
         * The client data contains the scanner ID and optional verification data.
         * @return
         */
        public BoolValue connect(ConnectionClientData clientData);

        /**
         * Sends a scan to all subscribers
         * @param scannedData contains the scanned data.
         *                    This can be either a ScannedBallot or a ScanError;
         *                    On the client side, this method can be called without setting
         *                    the signature field.
         * @return true iff the scanned data has been sent to at least one subscriber
         */
        public BoolValue newScan(SignedScannedData scannedData);
    }

    /**
     * An interface for submitting scanned data (scanner side)
     */
    public interface ScannerClient {

        /**
         * Connect to the polling station server.
         * The client data contains the scanner ID and optional verification data.
         * @return
         */
        public boolean connect(ConnectionServerData serverData);

        /**
         * Sends a scan to all subscribers
         * @param scannedBallot contains the scanned data.
         *                    This can be either a ScannedBallot or a ScanError;
         * @return true iff the scanned data has been sent to at least one subscriber
         */
        public boolean newScan(ScannedBallot scannedBallot);

        /**
         * Report a scan error to all subscribers
         * @param scanError
         * @return
         */
        public boolean reportError(ScanError scanError);
    }


    
}