package meerkat.bulletinboard.workers.singleserver;

import meerkat.bulletinboard.SingleServerWorker;
import meerkat.comm.CommunicationException;
import meerkat.comm.MessageInputStream;
import meerkat.protobuf.BulletinBoardApi;
import meerkat.protobuf.BulletinBoardApi.BulletinBoardMessageList;
import meerkat.protobuf.BulletinBoardApi.MessageFilterList;
import meerkat.protobuf.BulletinBoardApi.BulletinBoardMessage;
import meerkat.rest.Constants;

import javax.ws.rs.ProcessingException;
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 java.lang.reflect.InvocationTargetException;
import java.util.List;

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 SingleServerReadMessagesWorker extends SingleServerWorker<MessageFilterList, List<BulletinBoardMessage>> {

    public SingleServerReadMessagesWorker(String serverAddress, MessageFilterList payload, int maxRetry) {
        super(serverAddress, payload, maxRetry);
    }

    /**
     * This method carries out the actual communication with the server via HTTP Post
     * Upon successful retrieval from the server the method returns the received values
     * @return The list of messages returned by the server
     * @throws CommunicationException if the server's response is invalid
     */
    public List<BulletinBoardMessage> call() throws CommunicationException{

        Client client = clientLocal.get();

        WebTarget webTarget;

        // 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(payload, Constants.MEDIATYPE_PROTOBUF), InputStream.class);

        MessageInputStream<BulletinBoardMessage> inputStream = null;

        try {

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

            return inputStream.asList();

        } catch (IOException | InvocationTargetException e) {

            // Read failed
            throw new CommunicationException("Could not contact the server or server returned illegal result");

        } catch (NoSuchMethodException | IllegalAccessException e) {

            throw new CommunicationException("MessageInputStream error");

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

    }

}
