package com.segment.analytics;

import com.amplitude.api.Amplitude;
import java.util.Random;
import org.json.JSONObject;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Matchers;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PowerMockIgnore;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.rule.PowerMockRule;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;

import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.eq;
import static org.powermock.api.mockito.PowerMockito.verifyNoMoreInteractions;
import static org.powermock.api.mockito.PowerMockito.verifyStatic;

@RunWith(RobolectricTestRunner.class) @Config(emulateSdk = 18, manifest = Config.NONE)
@PowerMockIgnore({ "org.mockito.*", "org.robolectric.*", "android.*" })
@PrepareForTest(Amplitude.class)
public class AmplitudeTest extends IntegrationExam {
  @Rule public PowerMockRule rule = new PowerMockRule();

  AmplitudeIntegrationAdapter amplitudeIntegrationAdapter;

  @Before @Override public void setUp() {
    super.setUp();
    PowerMockito.mockStatic(Amplitude.class);
    amplitudeIntegrationAdapter = new AmplitudeIntegrationAdapter();
  }

  @Test public void initialize() throws InvalidConfigurationException {
    amplitudeIntegrationAdapter.initialize(context, //
        new JsonMap().putValue("apiKey", "foo")
            .putValue("trackAllPages", true)
            .putValue("trackCategorizedPages", false)
            .putValue("trackNamedPages", true)
    );
    verifyStatic();
    Amplitude.initialize(context, "foo");
    assertThat(amplitudeIntegrationAdapter.trackAllPages).isTrue();
    assertThat(amplitudeIntegrationAdapter.trackCategorizedPages).isFalse();
    assertThat(amplitudeIntegrationAdapter.trackNamedPages).isTrue();
    // Verify default args
    amplitudeIntegrationAdapter.initialize(context, //
        new JsonMap().putValue("apiKey", "foo"));
    assertThat(amplitudeIntegrationAdapter.trackAllPages).isFalse();
    assertThat(amplitudeIntegrationAdapter.trackCategorizedPages).isFalse();
    assertThat(amplitudeIntegrationAdapter.trackNamedPages).isFalse();
  }

  @Test
  public void track() {
    TrackPayload trackPayload = trackPayload("foo");
    amplitudeIntegrationAdapter.track(trackPayload);
    verifyStatic();
    Amplitude.logEvent(eq("foo"), any(JSONObject.class));
    verifyNoMoreInteractions(Amplitude.class);
  }

  @Test
  public void trackWithRevenue() {
    TrackPayload trackPayload = trackPayload("foo");
    trackPayload.properties()
        .putRevenue(20)
        .putValue("productId", "bar")
        .putValue("quantity", 10)
        .putValue("receipt", "baz")
        .putValue("receiptSignature", "qux");
    amplitudeIntegrationAdapter.track(trackPayload);
    verifyStatic();
    Amplitude.logEvent(eq("foo"), any(JSONObject.class));
    verifyStatic();
    Amplitude.logRevenue("bar", 10, 20, "baz", "qux");
  }

  @Test
  public void activityLifecycle() {
    amplitudeIntegrationAdapter.onActivityResumed(activity);
    verifyStatic();
    Amplitude.startSession();

    amplitudeIntegrationAdapter.onActivityPaused(activity);
    verifyStatic();
    Amplitude.endSession();

    amplitudeIntegrationAdapter.onActivityStarted(activity);
    amplitudeIntegrationAdapter.onActivityStopped(activity);
    amplitudeIntegrationAdapter.onActivityCreated(activity, bundle);
    amplitudeIntegrationAdapter.onActivityDestroyed(activity);
    amplitudeIntegrationAdapter.onActivitySaveInstanceState(activity, bundle);
    verifyNoMoreInteractions(Amplitude.class);
  }

  @Test
  public void identify() {
    IdentifyPayload payload = identifyPayload("michael");
    amplitudeIntegrationAdapter.identify(payload);
    verifyStatic();
    Amplitude.setUserId("michael");
    verifyStatic();
    Amplitude.setUserProperties(Matchers.<JSONObject>any());
    // todo: verify JSONObject
  }

  @Test
  public void screenTrackNothing() {
    amplitudeIntegrationAdapter.trackAllPages = false;
    amplitudeIntegrationAdapter.trackCategorizedPages = false;
    amplitudeIntegrationAdapter.trackNamedPages = false;
    amplitudeIntegrationAdapter.screen(screenPayload("foo", "bar"));
    verifyNoMoreInteractions(Amplitude.class);
  }

  @Test
  public void screenTrackNamedPages() {
    amplitudeIntegrationAdapter.trackAllPages = false;
    amplitudeIntegrationAdapter.trackCategorizedPages = false;
    amplitudeIntegrationAdapter.trackNamedPages = true;

    amplitudeIntegrationAdapter.screen(screenPayload(null, "bar"));
    verifyAmplitudeEvent("Viewed bar Screen", null);

    amplitudeIntegrationAdapter.screen(screenPayload("foo", null));
    verifyNoMoreInteractions(Amplitude.class);
  }

  @Test
  public void screenTrackCategorizedPages() {
    amplitudeIntegrationAdapter.trackAllPages = false;
    amplitudeIntegrationAdapter.trackCategorizedPages = true;
    amplitudeIntegrationAdapter.trackNamedPages = false;

    amplitudeIntegrationAdapter.screen(screenPayload("foo", null));
    verifyAmplitudeEvent("Viewed foo Screen", null);

    amplitudeIntegrationAdapter.screen(screenPayload(null, "bar"));
    verifyNoMoreInteractions(Amplitude.class);
  }

  @Test
  public void screenTrackAllPages() {
    amplitudeIntegrationAdapter.trackAllPages = true;
    amplitudeIntegrationAdapter.trackCategorizedPages = new Random().nextBoolean();
    amplitudeIntegrationAdapter.trackNamedPages = new Random().nextBoolean();

    amplitudeIntegrationAdapter.screen(screenPayload("foo", null));
    verifyAmplitudeEvent("Viewed foo Screen", null);

    amplitudeIntegrationAdapter.screen(screenPayload(null, "bar"));
    verifyAmplitudeEvent("Viewed bar Screen", null);

    amplitudeIntegrationAdapter.screen(screenPayload("bar", "baz"));
    verifyAmplitudeEvent("Viewed baz Screen", null);
  }

  @Test
  public void flush() {
    amplitudeIntegrationAdapter.flush();
    verifyStatic();
    Amplitude.uploadEvents();
  }

  private void verifyAmplitudeEvent(String event, JSONObject jsonObject) {
    verifyStatic();
    Amplitude.logEvent(eq(event), any(JSONObject.class));
  }
}

@@ -4390,32 +4390,52 @@
 %22foo%22, %22bar%22));%0A
+    verifyStatic();%0A
     verifyNoMore
@@ -4457,32 +4457,32 @@
 plitude.class);%0A
-
   %7D%0A%0A  @Test%0A  p
@@ -4875,32 +4875,52 @@
 (%22foo%22, null));%0A
+    verifyStatic();%0A
     verifyNoMore
@@ -5298,32 +5298,32 @@
 creen%22, null);%0A%0A
-
     amplitudeInt
@@ -5366,32 +5366,52 @@
 (null, %22bar%22));%0A
+    verifyStatic();%0A
     verifyNoMore

Call verifyStatic before testing