package com.mobify.astro.messaging;

import android.support.annotation.NonNull;
import android.util.Log;

import org.json.JSONException;
import org.json.JSONObject;

public class MessageSender {

    private static final String TAG = MessageSender.class.getName();

    private EventEmitter eventEmitter;

    public MessageSender(EventEmitter eventEmitter) {
        this.eventEmitter = eventEmitter;
    }

    /**
     * Sends a Message object to the supplied address
     *
     * @param message the Message to send
     * @param address the Address to send the Message to
     */
    public final void sendMessageToAddress(@NonNull Message message, @NonNull String address) {
        JSONObject serializedMessage;
        try {
            serializedMessage = message.toJSON();
        } catch (Exceptions.HeaderSerializationException e) {
            Log.e(TAG, "Error sending message to address " + address + ": " + e.getMessage(), e);
            return;
        }

        eventEmitter.trigger(address, serializedMessage);
    }

    /**
     * Sends an RpcResponse, and records it as sent.
     *
     * @param rpcResponse the RpcResponse to send
     * @throws com.mobify.astro.messaging.Exceptions.DuplicateRpcResponseSend If this response has already been sent
     */
    public void sendRpcResponse(@NonNull RpcResponse rpcResponse) throws Exceptions.DuplicateRpcResponseSend {
        if (rpcResponse.isSent()) {
            throw new Exceptions.DuplicateRpcResponseSend(rpcResponse);
        }
        sendMessageToAddress(rpcResponse, rpcResponse.getDestinationAddress());
        rpcResponse.responseSent();
    }

    /**
     * Populates the result and sends the RpcResponse in one go.
     *
     * @param rpcResponse the RpcResponse to send
     * @param result A JSON object representing the packed response of the RPC call
     * @throws com.mobify.astro.messaging.Exceptions.DuplicateRpcResponseSend If the response has already been sent
     * @throws org.json.JSONException
     */
    public void sendRpcResponseWithResult(@NonNull RpcResponse rpcResponse, Object result) throws JSONException, Exceptions.DuplicateRpcResponseSend {
        rpcResponse.setResult(result);
        sendRpcResponse(rpcResponse);
    }

    /**
     * Sets the error and sends the RpcResponse in one go
     *
     * @param rpcResponse the RpcResponse to send
     * @param e An Exception to report to the addressee of the response
     * @throws com.mobify.astro.messaging.Exceptions.DuplicateRpcResponseSend If the response has already been sent
     */
    public void sendRpcResponseWithError(@NonNull RpcResponse rpcResponse, @NonNull Exception e) throws Exceptions.DuplicateRpcResponseSend {
        rpcResponse.setError(e);
        sendRpcResponse(rpcResponse);
    }
}
