package com.bt.openlink.tinder.iq;

import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.Matchers.contains;
import static org.hamcrest.Matchers.empty;
import static org.junit.Assert.assertThat;
import static org.unitils.reflectionassert.ReflectionAssert.assertReflectionEquals;
import static org.xmlunit.matchers.CompareMatcher.isIdenticalTo;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Optional;

import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.xmpp.packet.IQ;

import com.bt.openlink.CallHistoryFixtures;
import com.bt.openlink.CoreFixtures;
import com.bt.openlink.tinder.Fixtures;
import com.bt.openlink.type.HistoricalCall;

public class GetCallHistoryResultTest {

    @Rule public final ExpectedException expectedException = ExpectedException.none();

    @Test
    public void canCreateAStanza() {

        final GetCallHistoryResult result = GetCallHistoryResult.Builder.start()
                .setId(CoreFixtures.STANZA_ID)
                .setTo(Fixtures.TO_JID)
                .setFrom(Fixtures.FROM_JID)
                .setFirstRecordNumber(0)
                .setRecordCountInBatch(1)
                .setTotalRecordCount(2)
                .addCall(CallHistoryFixtures.CALL)
                .build();

        assertThat(result.getType(), is(IQ.Type.result));
        assertThat(result.getID(), is(CoreFixtures.STANZA_ID));
        assertThat(result.getTo(), is(Fixtures.TO_JID));
        assertThat(result.getFrom(), is(Fixtures.FROM_JID));
        assertThat(result.getFirstRecordNumber(), is(Optional.of(0L)));
        assertThat(result.getRecordCountInBatch(), is(Optional.of(1L)));
        assertThat(result.getTotalRecordCount(), is(Optional.of(2L)));
        assertThat(result.getCalls(), contains(CallHistoryFixtures.CALL));
    }

    @Test
    public void willGenerateAnXmppStanza() {

        final GetCallHistoryResult result = GetCallHistoryResult.Builder.start()
                .setId(CoreFixtures.STANZA_ID)
                .setTo(Fixtures.TO_JID)
                .setFrom(Fixtures.FROM_JID)
                .setFirstRecordNumber(0)
                .setRecordCountInBatch(1)
                .setTotalRecordCount(2)
                .addCall(CallHistoryFixtures.CALL)
                .build();

        assertThat(result.toXML(), isIdenticalTo(CallHistoryFixtures.CALL_HISTORY_RESULT).ignoreWhitespace());
    }

    @Test
    public void willParseAnXMPPStanza() {
        final GetCallHistoryResult result = OpenlinkIQParser.parse(Fixtures.iqFrom(CallHistoryFixtures.CALL_HISTORY_RESULT));

        assertThat(result.getType(), is(IQ.Type.result));
        assertThat(result.getID(), is(CoreFixtures.STANZA_ID));
        assertThat(result.getTo(), is(Fixtures.TO_JID));
        assertThat(result.getFrom(), is(Fixtures.FROM_JID));
        assertThat(result.getFirstRecordNumber(), is(Optional.of(0L)));
        assertThat(result.getRecordCountInBatch(), is(Optional.of(1L)));
        assertThat(result.getTotalRecordCount(), is(Optional.of(2L)));
        assertReflectionEquals(Collections.singletonList(CallHistoryFixtures.CALL), result.getCalls());
        assertThat(result.getParseErrors(),is(empty()));
    }

    @Test
    public void willReturnParsingErrors() {
        final GetCallHistoryResult result = OpenlinkIQParser.parse(Fixtures.iqFrom(CallHistoryFixtures.CALL_HISTORY_RESULT_WITH_BAD_VALUES));

        assertThat(result.getType(), is(IQ.Type.get));
        assertThat(result.getFirstRecordNumber(), is(Optional.empty()));
        assertThat(result.getRecordCountInBatch(), is(Optional.of(2L)));
        assertThat(result.getTotalRecordCount(), is(Optional.empty()));
        assertReflectionEquals(Collections.singletonList(HistoricalCall.Builder.start().build(new ArrayList<>())), result.getCalls());
        assertThat(result.getParseErrors(),contains(
                "Invalid get-call-history result; invalid duration 'not-a-duration'; please supply an integer",
                "Invalid get-call-history result; invalid timestamp 'not-a-timestamp'; please supply a valid timestamp",
                "Invalid historical call; missing call id is mandatory",
                "Invalid historical call; missing profile id is mandatory",
                "Invalid historical call; missing interest id is mandatory",
                "Invalid historical call; missing state is mandatory",
                "Invalid historical call; missing direction is mandatory",
                "Invalid historical call; missing caller number is mandatory",
                "Invalid historical call; missing caller name is mandatory",
                "Invalid historical call; missing called number is mandatory",
                "Invalid historical call; missing called name is mandatory",
                "Invalid historical call; missing start time is mandatory",
                "Invalid historical call; missing duration is mandatory",
                "Invalid historical call; missing TSC is mandatory",
                "Invalid stanza; missing 'to' attribute is mandatory",
                "Invalid stanza; missing 'from' attribute is mandatory",
                "Invalid stanza; missing 'id' attribute is mandatory",
                "Invalid stanza; incorrect 'type' attribute: get",
                "Invalid call history; missing or invalid total record count",
                "Invalid call history; missing or invalid first record number",
                "Invalid call history; incorrect batch record count"
                ));
    }
}
@@ -440,16 +440,92 @@
 tional;%0A
+import java.util.TimeZone;%0A%0Aimport org.junit.After;%0Aimport org.junit.Before;
 %0Aimport 
@@ -926,16 +926,309 @@
 .none();
+%0A    private TimeZone defaultTimeZone;%0A%0A    @Before%0A    public void setUp() %7B%0A        defaultTimeZone = TimeZone.getDefault();%0A        TimeZone.setDefault(TimeZone.getTimeZone(%22Europe/London%22));%0A    %7D%0A%0A    @After%0A    public void tearDown() %7B%0A        TimeZone.setDefault(defaultTimeZone);%0A    %7D
 %0A%0A    @T
@@ -3589,16 +3589,17 @@
 rrors(),
+ 
 is(empty
@@ -4259,16 +4259,17 @@
 rrors(),
+ 
 contains
@@ -5915,33 +5915,16 @@
 d count%22
-%0A                
 ));%0A    

Fix build for non-UK timezones