package com.telecomsys.cmc;

import java.util.ArrayList;
import java.util.List;

import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;

import com.github.tomakehurst.wiremock.junit.WireMockRule;
import com.github.tomakehurst.wiremock.verification.LoggedRequest;
import com.telecomsys.cmc.api.MessagingApi;
import com.telecomsys.cmc.exception.CMCAuthenticationException;
import com.telecomsys.cmc.exception.CMCException;
import com.telecomsys.cmc.exception.CMCIOException;
import com.telecomsys.cmc.exception.CMCServerException;
import com.telecomsys.cmc.http.HttpResponseWrapper;
import com.telecomsys.cmc.model.Message;
import com.telecomsys.cmc.response.NotificationsResponse;
import com.telecomsys.cmc.response.RestResponse;

import static com.github.tomakehurst.wiremock.client.WireMock.*;
import static org.junit.Assert.*;

public class MessagingApiTest {
    
    /**
     * CMC REST user name (account ID).
     */
    private static final String USERNAME = "9876";

    /**
     * CMC REST user name (account ID).
     */
    private static final String PASSWORD = "1234";

    /**
     * CMC REST connection keyword.
     */
    private static final String REST_CONNECTION_KEYWORD = "scsrest"; 
    
    /**
     * CMC client instance.
     */
    private MessagingApi messagingApi;
    
    @Rule
    public WireMockRule wireMockRule = new WireMockRule(18089);
    
    @Before
    public void setup() {
        messagingApi = new MessagingApi("http://localhost:18089", USERNAME, PASSWORD);
    }
    
    @Test(expected=CMCIOException.class)
    public void invalidHostTest() throws CMCException {
        MessagingApi invalidMessagingApi = new MessagingApi("http://invalidHost:1234", USERNAME, PASSWORD);
        List<String> destinations = new ArrayList<String>();
        destinations.add("4102804827");   
        Message message = new Message(destinations, REST_CONNECTION_KEYWORD, "Test message");
        invalidMessagingApi.sendMessage(message);        
    }
    
    @Test(expected=CMCAuthenticationException.class)
    public void invalidCredentialsTest() throws CMCException {
        stubFor(post(urlEqualTo("/messages"))
                .willReturn(aResponse()
                    .withStatus(401)
                    .withHeader("Content-Type", "text/html")
                    .withBody("This request requires HTTP authentication.")));
        
        List<String> destinations = new ArrayList<String>();
        destinations.add("4102804827");
        Message message = new Message(destinations, REST_CONNECTION_KEYWORD, "Test message");
        messagingApi.sendMessage(message);
    }     
    
    @Test
    public void invalidKeywordTest() throws CMCException {
        stubFor(post(urlEqualTo("/messages"))
                .willReturn(aResponse()
                    .withStatus(404)
                    .withHeader("Content-Type", "application/json")
                    .withBody("{\"response\":{\"status\":\"fail\",\"code\":\"1010\",\"message\":\"Your message failed: Invalid from address.\"}}")));        
        
        try { 
            List<String> destinations = new ArrayList<String>();
            destinations.add("4102804827");
            Message message = new Message(destinations, REST_CONNECTION_KEYWORD, "Test message");
            messagingApi.sendMessage(message);
        } catch (CMCServerException cmex) {
            RestResponse error = cmex.getError();
            assertEquals(error.getStatus(), "fail");
            assertEquals(error.getCode(), "1010");
            assertEquals(error.getMessage(), "Your message failed: Invalid from address.");
        }
    }
    
    @Test
    public void sendMessagesSingleDestination() throws CMCException {
        stubFor(post(urlEqualTo("/messages"))
                .willReturn(aResponse()
                    .withStatus(200)
                    .withHeader("Content-Type", "application/json")
                    .withBody("{\"response\":{\"status\":\"success\",\"notifications\":{\"to\":[\"4102804827\"],\"from\":\"scsrest\",\"trackinginformation\":{\"destination\":\"4102804827\",\"messagestatus\":\"Message Accepted\",\"messageID\":\"GW1_AVvciGlHRM32pw0Q\",\"messagetext\":\"Test message\"}]}}}")));        
        
        List<String> destinations = new ArrayList<String>();
        destinations.add("4102804827"); 
        Message message = new Message(destinations, REST_CONNECTION_KEYWORD, "Test message");
        HttpResponseWrapper<NotificationsResponse> response = messagingApi.sendMessage(message);
        
        // Verify the response
        assertEquals(response.getHttpStatusCode(), 200);
        
        // Verify the request
        List<LoggedRequest> requests = findAll(postRequestedFor(urlMatching("/messages")));
        assertEquals(requests.size(), 1);
        assertEquals(requests.get(0).getBodyAsString(), "{\"sendmessage\":{\"message\":\"Test message\",\"to\":[\"4102804827\"],\"from\":\"scsrest\"}}");
    }    
    
}

@@ -631,16 +631,66 @@
 essage;%0A
+import com.telecomsys.cmc.response.Notifications;%0A
 import c
@@ -787,16 +787,72 @@
 esponse;
+%0Aimport com.telecomsys.cmc.response.TrackingInformation;
 %0A%0Aimport
@@ -4177,16 +4177,17 @@
 ation%5C%22:
+%5B
 %7B%5C%22desti
@@ -4738,16 +4738,682 @@
 , 200);%0A
+        Notifications notifications = response.getResponseBody().getNotifications();%0A        assertEquals(notifications.getFromAddress(),%22scsrest%22);%0A        assertEquals(notifications.getTo().size(),1);%0A        assertEquals(notifications.getTo().get(0),%224102804827%22);%0A        List%3CTrackingInformation%3E trackingInformation = notifications.getTrackingInformation();%0A        assertEquals(trackingInformation.size(),1);%0A        assertEquals(trackingInformation.get(0).getDestination(),%224102804827%22);%0A        assertEquals(trackingInformation.get(0).getMessageID(),%22GW1_AVvciGlHRM32pw0Q%22);%0A        assertEquals(trackingInformation.get(0).getMessageText(),%22Test message%22);%0A
         

Send message implementation.