package com.f2prateek.segment;

import android.Manifest;
import android.app.Application;
import com.squareup.moshi.Moshi;
import com.squareup.moshi.Rfc3339DateJsonAdapter;
import java.util.Date;
import okhttp3.mockwebserver.MockResponse;
import okhttp3.mockwebserver.MockWebServer;
import okhttp3.mockwebserver.RecordedRequest;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.Shadows;
import org.robolectric.annotation.Config;
import org.robolectric.shadows.ShadowApplication;

import static com.google.common.truth.Truth.assertThat;

@RunWith(RobolectricTestRunner.class) //
@Config(constants = BuildConfig.class, sdk = 23) //
public class SegmentTest {
  @Rule public final MockWebServer server = new MockWebServer();
  private Segment segment;

  private static void grantPermission(final Application app, final String permission) {
    ShadowApplication shadowApp = Shadows.shadowOf(app);
    shadowApp.grantPermissions(permission);
  }

  @Before public void setUp() {
    grantPermission(RuntimeEnvironment.application, Manifest.permission.INTERNET);

    segment = new Segment.Builder() //
        .writeKey("writeKey") //
        .context(RuntimeEnvironment.application) //
        .baseUrl(server.url("/")) //
        .build();
  }

  @Test public void e2e() throws Exception {
    server.enqueue(new MockResponse());

    segment.enqueue(segment.newTrack("event").build());
    segment.flush().get();

    RecordedRequest request = server.takeRequest();
    assertThat(request.getRequestLine()).isEqualTo("POST /v1/batch HTTP/1.1");
    //noinspection SpellCheckingInspection
    assertThat(request.getHeader("Authorization")).isEqualTo("Basic d3JpdGVLZXk6");

    // TODO: Use proper fixtures. Currently IDs and timestamps are not consistent between runs.
    final Moshi moshi = new Moshi.Builder() //
        .add(SegmentMoshiAdapterFactory.create()) //
        .add(Date.class, new Rfc3339DateJsonAdapter()) //
        .build();
    Batch batch = moshi.adapter(Batch.class).fromJson(request.getBody());
    assertThat(batch.batch()).hasSize(1);
    assertThat(((TrackMessage) batch.batch().get(0)).event()).isEqualTo("event");
  }
}

@@ -182,20 +182,68 @@
 va.util.
-Date
+Arrays;%0Aimport java.util.Date;%0Aimport java.util.List
 ;%0Aimport
@@ -1500,105 +1500,377 @@
 n %7B%0A
+%0A
     
-server.enqueue(new MockResponse());%0A%0A    segment.enqueue(segment.newTrack(%22event%22).build());%0A
+List%3CMessage%3E messages =%0A        Arrays.asList(segment.newAlias(%22newId%22).build(), segment.newGroup(%22groupId%22).build(),%0A            segment.newIdentify(%22userId%22).build(), segment.newScreen(%22name%22).build(),%0A            segment.newTrack(%22event%22).build());%0A%0A    for (Message m : messages) %7B%0A      server.enqueue(new MockResponse());%0A%0A      segment.enqueue(m).get();%0A  
     
@@ -1897,16 +1897,18 @@
 );%0A%0A    
+  
 Recorded
@@ -1943,24 +1943,26 @@
 eRequest();%0A
+  
     assertTh
@@ -2028,16 +2028,18 @@
 /1.1%22);%0A
+  
     //no
@@ -2073,24 +2073,26 @@
 pection%0A    
+  
 assertThat(r
@@ -2156,24 +2156,26 @@
 GVLZXk6%22);%0A%0A
+  
     // TODO:
@@ -2258,16 +2258,18 @@
 n runs.%0A
+  
     fina
@@ -2311,24 +2311,26 @@
  //%0A        
+  
 .add(Segment
@@ -2358,24 +2358,26 @@
 reate()) //%0A
+  
         .add
@@ -2422,32 +2422,34 @@
 r()) //%0A        
+ 
+ 
 .build();%0A    Ba
@@ -2438,24 +2438,26 @@
   .build();%0A
+  
     Batch ba
@@ -2518,24 +2518,26 @@
 ody());%0A    
+  
 assertThat(b
@@ -2562,24 +2562,26 @@
 ize(1);%0A    
+  
 assertThat((
@@ -2583,24 +2583,8 @@
 hat(
-((TrackMessage) 
 batc
@@ -2605,17 +2605,8 @@
 0)).
-event()).
 isEq
@@ -2615,17 +2615,17 @@
 lTo(
-%22event%22);
+m);%0A    %7D
 %0A  %7D

Add flush test for all messages