package com.amplitude.api;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;

import com.squareup.okhttp.mockwebserver.RecordedRequest;

import org.json.JSONException;
import org.json.JSONObject;
import org.json.JSONArray;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.Shadows;
import org.robolectric.annotation.Config;
import org.robolectric.shadows.ShadowApplication;
import org.robolectric.shadows.ShadowLooper;

import android.content.Context;

@RunWith(RobolectricTestRunner.class)
@Config(manifest = Config.NONE)
public class SessionTest extends BaseTest {

    @Before
    public void setUp() throws Exception {
        super.setUp();
    }

    @After
    public void tearDown() throws Exception {
        super.tearDown();
    }


// TODO: Add a bunch of tests around starting and ending sessions

    @Test
    public void testStartSession() {
        amplitude.startSession();
        Shadows.shadowOf(amplitude.logThread.getLooper()).runToEndOfTasks();

        JSONObject event = getLastUnsentEvent();
        assertEquals(AmplitudeClient.START_SESSION_EVENT, event.optString("event_type"));
        assertEquals(AmplitudeClient.START_SESSION_EVENT, event.optJSONObject("api_properties").optString("special"));

        assertEquals(1, getUnsentEventCount());
        assertNotNull(runRequest());
    }

    @Test
    public void testImplicitStartSession() {
        amplitude.logEvent("implicit_start_session");
        Shadows.shadowOf(amplitude.logThread.getLooper()).runToEndOfTasks();
        Shadows.shadowOf(amplitude.logThread.getLooper()).runToEndOfTasks();

        JSONArray events = getUnsentEvents(2);
        
        JSONObject event = events.optJSONObject(0);
        assertEquals(AmplitudeClient.START_SESSION_EVENT, event.optString("event_type"));
        assertEquals(AmplitudeClient.START_SESSION_EVENT, event.optJSONObject("api_properties").optString("special"));

        event = events.optJSONObject(1);
        assertEquals("implicit_start_session", event.optString("event_type"));

        assertEquals(2, getUnsentEventCount());
        assertNotNull(runRequest());
    }

    @Test
    public void testEndSession() {
        amplitude.endSession();
        Shadows.shadowOf(amplitude.logThread.getLooper()).runToEndOfTasks();
        assertEquals(0, getUnsentEventCount());

        amplitude.startSession();
        Shadows.shadowOf(amplitude.logThread.getLooper()).runToEndOfTasks();
        amplitude.endSession();
        Shadows.shadowOf(amplitude.logThread.getLooper()).runToEndOfTasks();

        JSONObject event = getLastUnsentEvent();
        assertEquals(AmplitudeClient.END_SESSION_EVENT, event.optString("event_type"));
        assertEquals(AmplitudeClient.END_SESSION_EVENT, event.optJSONObject("api_properties").optString("special"));

        assertEquals(2, getUnsentEventCount());
        assertNotNull(runRequest());
    }
}

@@ -1036,76 +1036,8 @@
  %7D%0A%0A
-%0A// TODO: Add a bunch of tests around starting and ending sessions%0A%0A
     
@@ -3106,11 +3106,1680 @@
 );%0A    %7D
+%0A%0A    @Test%0A    public void testContinueSession() %7B%0A        amplitude.startSession();%0A        Shadows.shadowOf(amplitude.logThread.getLooper()).runToEndOfTasks();%0A%0A        JSONObject event = getLastUnsentEvent();%0A        long session_id = event.optLong(%22session_id%22);%0A%0A        amplitude.endSession();%0A        Shadows.shadowOf(amplitude.logThread.getLooper()).runOneTask();%0A%0A        amplitude.startSession();%0A        Shadows.shadowOf(amplitude.logThread.getLooper()).runToEndOfTasks();%0A        assertEquals(1, getUnsentEventCount());%0A%0A        amplitude.logEvent(%22event%22);%0A        Shadows.shadowOf(amplitude.logThread.getLooper()).runToEndOfTasks();%0A        Shadows.shadowOf(amplitude.logThread.getLooper()).runToEndOfTasks();%0A%0A        event = getLastUnsentEvent();%0A        assertEquals(session_id, event.optLong(%22session_id%22));%0A    %7D%0A%0A    @Test%0A    public void testExpiredSession() %7B%0A        amplitude.startSession();%0A        Shadows.shadowOf(amplitude.logThread.getLooper()).runToEndOfTasks();%0A%0A        JSONObject event = getLastUnsentEvent();%0A        long session_id = event.optLong(%22session_id%22);%0A%0A        amplitude.endSession();%0A        Shadows.shadowOf(amplitude.logThread.getLooper()).runToEndOfTasks();%0A%0A        amplitude.startSession();%0A        Shadows.shadowOf(amplitude.logThread.getLooper()).runToEndOfTasks();%0A        assertEquals(3, getUnsentEventCount());%0A%0A        amplitude.logEvent(%22event%22);%0A        Shadows.shadowOf(amplitude.logThread.getLooper()).runToEndOfTasks();%0A        Shadows.shadowOf(amplitude.logThread.getLooper()).runToEndOfTasks();%0A%0A        event = getLastUnsentEvent();%0A        assertFalse(session_id == event.optLong(%22session_id%22));%0A    %7D
 %0A%7D%0A

Add more session tests