package com.braintreepayments.api;

import android.content.Context;
import android.net.Uri;

import androidx.annotation.Nullable;
import androidx.annotation.VisibleForTesting;

import org.json.JSONException;

class PayPalInternalClient {

    private static final String CREATE_SINGLE_PAYMENT_ENDPOINT = "paypal_hermes/create_payment_resource";
    private static final String SETUP_BILLING_AGREEMENT_ENDPOINT = "paypal_hermes/setup_billing_agreement";

    private static final String USER_ACTION_KEY = "useraction";

    private final String cancelUrl;
    private final String successUrl;

    private final BraintreeClient braintreeClient;
    private final PayPalDataCollector payPalDataCollector;

    PayPalInternalClient(BraintreeClient braintreeClient) {
        this(braintreeClient, new PayPalDataCollector());
    }

    @VisibleForTesting
    PayPalInternalClient(BraintreeClient braintreeClient, PayPalDataCollector payPalDataCollector) {
        this.braintreeClient = braintreeClient;
        this.payPalDataCollector = payPalDataCollector;

        this.cancelUrl = String.format("%s://onetouch/v1/cancel", braintreeClient.getReturnUrlScheme());
        this.successUrl = String.format("%s://onetouch/v1/success", braintreeClient.getReturnUrlScheme());
    }

    void sendRequest(final Context context, final PayPalRequest payPalRequest, final PayPalInternalClientCallback callback) {
        braintreeClient.getConfiguration(new ConfigurationCallback() {
            @Override
            public void onResult(@Nullable Configuration configuration, @Nullable Exception error) {
                if (configuration == null) {
                    callback.onResult(null, error);
                    return;
                }
                try {
                    final boolean isBillingAgreement = payPalRequest instanceof PayPalVaultRequest;
                    String endpoint = isBillingAgreement
                            ? SETUP_BILLING_AGREEMENT_ENDPOINT : CREATE_SINGLE_PAYMENT_ENDPOINT;
                    String url = String.format("/v1/%s", endpoint);

                    String requestBody = payPalRequest.createRequestBody(configuration, braintreeClient.getAuthorization(), successUrl, cancelUrl);

                    braintreeClient.sendPOST(url, requestBody, new HTTPResponseCallback() {

                        @Override
                        public void onResult(String responseBody, Exception httpError) {
                            if (httpError != null) {
                                callback.onResult(null, httpError);
                                return;
                            }

                            try {
                                PayPalResponse payPalResponse = new PayPalResponse(payPalRequest)
                                        .successUrl(successUrl);

                                PayPalPaymentResource paypalPaymentResource = PayPalPaymentResource.fromJson(responseBody);
                                String redirectUrl = paypalPaymentResource.getRedirectUrl();
                                if (redirectUrl != null) {
                                    Uri parsedRedirectUri = Uri.parse(redirectUrl);

                                    String pairingIdKey = isBillingAgreement ? "ba_token" : "token";
                                    String pairingId = parsedRedirectUri.getQueryParameter(pairingIdKey);

                                    if (pairingId != null) {
                                        payPalResponse
                                                .pairingId(pairingId)
                                                .clientMetadataId(payPalDataCollector.getClientMetadataId(context));
                                    }

                                    String approvalUrl = parsedRedirectUri
                                            .buildUpon()
                                            .appendQueryParameter(USER_ACTION_KEY, payPalResponse.getUserAction())
                                            .toString();
                                    payPalResponse.approvalUrl(approvalUrl);
                                }
                                callback.onResult(payPalResponse, null);

                            } catch (JSONException exception) {
                                callback.onResult(null, exception);
                            }
                        }
                    });
                } catch (JSONException exception) {
                    callback.onResult(null, exception);
                }

            }
        });
    }
}

@@ -2475,25 +2475,28 @@
     if (
-httpError
+responseBody
  != null
@@ -2535,149 +2535,29 @@
     
-callback.onResult(null, httpError);%0A                                return;%0A                            %7D%0A%0A                            try %7B%0A
+try %7B%0A               
     
@@ -2569,35 +2569,24 @@
             
-           
 PayPalRespon
@@ -2679,16 +2679,20 @@
         
+ 
+   
 .success
@@ -2705,24 +2705,28 @@
 ccessUrl);%0A%0A
+    
             
@@ -2861,32 +2861,36 @@
                 
+    
 String redirectU
@@ -2962,24 +2962,28 @@
             
+ 
+   
 if (redirect
@@ -2989,32 +2989,36 @@
 tUrl != null) %7B%0A
+    
                 
@@ -3114,32 +3114,36 @@
                 
+    
 String pairingId
@@ -3219,32 +3219,36 @@
                 
+ 
+   
 String pairingId
@@ -3334,24 +3334,28 @@
             
+    
 if (pairingI
@@ -3359,32 +3359,36 @@
 ngId != null) %7B%0A
+    
                 
@@ -3474,16 +3474,20 @@
         
+    
 .pairing
@@ -3500,16 +3500,20 @@
 ringId)%0A
+    
         
@@ -3617,24 +3617,28 @@
 (context));%0A
+    
             
@@ -3696,24 +3696,28 @@
             
+    
 String appro
@@ -3787,16 +3787,20 @@
         
+    
 .buildUp
@@ -3804,16 +3804,20 @@
 dUpon()%0A
+    
         
@@ -3967,16 +3967,20 @@
         
+    
 .toStrin
@@ -3980,24 +3980,28 @@
 toString();%0A
+    
             
@@ -4065,16 +4065,20 @@
 alUrl);%0A
+    
         
@@ -4127,32 +4127,36 @@
                 
+    
 callback.onResul
@@ -4201,32 +4201,36 @@
                 
+    
 %7D catch (JSONExc
@@ -4273,32 +4273,36 @@
                 
+   
+ 
 callback.onResul
@@ -4313,32 +4313,171 @@
 ll, exception);%0A
+                                %7D%0A                            %7D else %7B%0A                                callback.onResult(null, httpError);%0A
                 

Use response body null check pattern when sending a PayPal request.