package meerkat.bulletinboard.workers.singleserver;

import meerkat.bulletinboard.SingleServerWorker;
import meerkat.comm.CommunicationException;
import meerkat.comm.MessageInputStream;
import meerkat.protobuf.BulletinBoardApi.*;
import meerkat.rest.Constants;

import javax.ws.rs.client.Client;
import javax.ws.rs.client.Entity;
import javax.ws.rs.client.WebTarget;
import javax.ws.rs.core.Response;

import java.io.IOException;
import java.io.InputStream;

import static meerkat.bulletinboard.BulletinBoardConstants.BULLETIN_BOARD_SERVER_PATH;
import static meerkat.bulletinboard.BulletinBoardConstants.READ_MESSAGES_PATH;

/**
 * Created by Arbel Deutsch Peled on 27-Dec-15.
 */
public class SingleServerGetRedundancyWorker extends SingleServerWorker<MessageID, Float> {

    public SingleServerGetRedundancyWorker(String serverAddress, MessageID payload, int maxRetry) {
        super(serverAddress, payload, maxRetry);
    }

    /**
     * This method carries out the actual communication with the server via HTTP Post
     * It queries the server for a message with the given ID
     * @return TRUE if the message exists in the server and FALSE otherwise
     * @throws CommunicationException if the server does not return a valid answer
     */
    public Float call() throws CommunicationException{

        Client client = clientLocal.get();

        WebTarget webTarget;
        Response response;

        MessageFilterList msgFilterList = MessageFilterList.newBuilder()
                .addFilter(MessageFilter.newBuilder()
                        .setType(FilterType.MSG_ID)
                        .setId(payload.getID())
                        .build()
                ).build();

        // Send request to Server

        // Send request to Server
        webTarget = client.target(serverAddress).path(BULLETIN_BOARD_SERVER_PATH).path(READ_MESSAGES_PATH);
        InputStream in = webTarget.request(Constants.MEDIATYPE_PROTOBUF).post(Entity.entity(msgFilterList, Constants.MEDIATYPE_PROTOBUF), InputStream.class);

        MessageInputStream<BulletinBoardMessage> inputStream = null;

        // Retrieve answer

        try {

            inputStream = MessageInputStream.MessageInputStreamFactory.createMessageInputStream(in, BulletinBoardMessage.class);

            if (inputStream.asList().size() > 0){
                // Message exists in the server
                return 1.0f;
            }
            else {
                // Message does not exist in the server
                return 0.0f;
            }

        } catch (Exception e) {

            // Read failed
            throw new CommunicationException("Server access failed");

        } finally {
            try {
                inputStream.close();
            } catch (IOException ignored) {}
        }

    }

}
