package com.braintreepayments.demo.test;

import android.test.suitebuilder.annotation.MediumTest;

import com.braintreepayments.demo.Settings;
import com.braintreepayments.demo.internal.ApiClient;
import com.braintreepayments.demo.internal.ApiClientRequestInterceptor;
import com.braintreepayments.demo.models.ClientToken;
import com.braintreepayments.demo.models.Transaction;

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

import java.util.concurrent.CountDownLatch;

import retrofit.Callback;
import retrofit.RestAdapter;
import retrofit.RestAdapter.LogLevel;
import retrofit.RetrofitError;
import retrofit.client.Response;

import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertNotNull;
import static junit.framework.Assert.assertTrue;
import static junit.framework.Assert.fail;

public class ApiClientTest {

    private CountDownLatch mCountDownLatch;
    private ApiClient mApiClient;

    @Before
    public void setup() {
        mCountDownLatch = new CountDownLatch(1);
        mApiClient = new RestAdapter.Builder()
                .setEndpoint(Settings.getSandboxUrl())
                .setRequestInterceptor(new ApiClientRequestInterceptor())
                .setLogLevel(LogLevel.FULL)
                .build()
                .create(ApiClient.class);
    }

    @Test(timeout = 10000)
    @MediumTest
    public void getClientToken_returnsAClientToken() throws InterruptedException {
        mApiClient.getClientToken(null, null, new Callback<ClientToken>() {
            @Override
            public void success(ClientToken clientToken, Response response) {
                assertNotNull(clientToken.getClientToken());
                mCountDownLatch.countDown();
            }

            @Override
            public void failure(RetrofitError retrofitError) {
                fail(retrofitError.getMessage());
            }
        });

        mCountDownLatch.await();
    }

    @Test(timeout = 10000)
    @MediumTest
    public void getClientToken_returnsAClientTokenForACustomer() throws InterruptedException {
        mApiClient.getClientToken("customer", null, new Callback<ClientToken>() {
            @Override
            public void success(ClientToken clientToken, Response response) {
                assertNotNull(clientToken.getClientToken());
                mCountDownLatch.countDown();
            }

            @Override
            public void failure(RetrofitError retrofitError) {
                fail(retrofitError.getMessage());
            }
        });

        mCountDownLatch.await();
    }

    @Test(timeout = 10000)
    @MediumTest
    public void getClientToken_returnsAClientTokenForAMerchantAccount() throws InterruptedException {
        mApiClient.getClientToken(null, "test_AIB", new Callback<ClientToken>() {
            @Override
            public void success(ClientToken clientToken, Response response) {
                assertNotNull(clientToken.getClientToken());
                mCountDownLatch.countDown();
            }

            @Override
            public void failure(RetrofitError retrofitError) {
                fail(retrofitError.getMessage());
            }
        });

        mCountDownLatch.await();
    }

    @Test(timeout = 10000)
    @MediumTest
    public void createTransaction_createsATransaction() throws InterruptedException {
        mApiClient.createTransaction("fake-valid-nonce", new Callback<Transaction>() {
            @Override
            public void success(Transaction transaction, Response response) {
                assertTrue(transaction.getMessage().contains("created") && transaction.getMessage().contains("authorized"));
                mCountDownLatch.countDown();
            }

            @Override
            public void failure(RetrofitError error) {
                fail(error.getMessage());
            }
        });

        mCountDownLatch.await();
    }

    @Test(timeout = 10000)
    @MediumTest
    public void createTransaction_failsWhenNonceIsAlreadyConsumed() throws InterruptedException {
        mApiClient.createTransaction("fake-consumed-nonce", null, false, new Callback<Transaction>() {
            @Override
            public void success(Transaction transaction, Response response) {
                assertEquals("Cannot use a payment_method_nonce more than once.", transaction.getMessage());
                mCountDownLatch.countDown();
            }

            @Override
            public void failure(RetrofitError error) {
                fail(error.getMessage());
            }
        });

        mCountDownLatch.await();
    }

    @Test(timeout = 10000)
    @MediumTest
    public void createTransaction_failsWhenThreeDSecureIsRequired() throws InterruptedException {
        mApiClient.createTransaction("fake-valid-nonce", "test_AIB", true,
                new Callback<Transaction>() {
                    @Override
                    public void success(Transaction transaction, Response response) {
                        assertEquals("Gateway Rejected: three_d_secure", transaction.getMessage());
                        mCountDownLatch.countDown();
                    }

                    @Override
                    public void failure(RetrofitError error) {
                        fail(error.getMessage());
                    }
                });

        mCountDownLatch.await();
    }

    @Test(timeout = 10000)
    @MediumTest
    public void createTransaction_doesNotFailWhenThreeDSecureIsNotRequired() throws InterruptedException {
        mApiClient.createTransaction("fake-valid-nonce", "test_AIB", new Callback<Transaction>() {
            @Override
            public void success(Transaction transaction, Response response) {
                assertTrue(transaction.getMessage().contains("created") && transaction.getMessage().contains("authorized"));
                mCountDownLatch.countDown();
            }

            @Override
            public void failure(RetrofitError error) {
                fail(error.getMessage());
            }
        });

        mCountDownLatch.await();
    }

    @Test(timeout = 10000)
    @MediumTest
    public void createTransaction_createsAUnionPayTransaction() throws InterruptedException {
        mApiClient.createTransaction("fake-valid-unionpay-credit-nonce", "fake_switch_usd",
                new Callback<Transaction>() {
                    @Override
                    public void success(Transaction transaction, Response response) {
                        assertTrue(transaction.getMessage().contains("created") && transaction.getMessage().contains("authorized"));
                        mCountDownLatch.countDown();
                    }

                    @Override
                    public void failure(RetrofitError error) {
                        fail(error.getMessage());
                    }
                });

        mCountDownLatch.await();
    }
}

@@ -2763,24 +2763,31 @@
 (null, %22
-test_AIB
+fake_switch_usd
 %22, new C
@@ -4125,21 +4125,8 @@
 ce%22,
- null, false,
  new
@@ -4809,41 +4809,19 @@
 e%22, 
-%22test_AIB%22, true,%0A               
+null, true,
  new
@@ -4855,32 +4855,24 @@
             
-        
 @Override%0A  
@@ -4865,32 +4865,24 @@
   @Override%0A
-        
             
@@ -4959,32 +4959,24 @@
             
-      
-  
 assertEquals
@@ -5043,784 +5043,8 @@
 ));%0A
-                        mCountDownLatch.countDown();%0A                    %7D%0A%0A                    @Override%0A                    public void failure(RetrofitError error) %7B%0A                        fail(error.getMessage());%0A                    %7D%0A                %7D);%0A%0A        mCountDownLatch.await();%0A    %7D%0A%0A    @Test(timeout = 10000)%0A    @MediumTest%0A    public void createTransaction_doesNotFailWhenThreeDSecureIsNotRequired() throws InterruptedException %7B%0A        mApiClient.createTransaction(%22fake-valid-nonce%22, %22test_AIB%22, new Callback%3CTransaction%3E() %7B%0A            @Override%0A            public void success(Transaction transaction, Response response) %7B%0A                assertTrue(transaction.getMessage().contains(%22created%22) && transaction.getMessage().contains(%22authorized%22));%0A
     

Fix ApiClient test setup