package br.com.gerencianet.sdk.android;

import android.content.res.AssetManager;

import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.security.KeyStore;
import java.security.SecureRandom;
import java.util.Date;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import com.google.gson.JsonObject;
import br.com.gerencianet.sdk.android.exceptions.AuthorizationException;
import br.com.gerencianet.sdk.android.exceptions.GerencianetException;

public class APIRequest {
    private final Request requester;
    private final Auth authenticator;
    private final JsonObject body;

    public APIRequest(String method, String route, JsonObject body, Config config, AssetManager cert) throws Exception {
        String authenticateRoute = config.getEndpoints().getAsJsonObject("authorize").get("route").getAsString();
        String authenticateMethod = config.getEndpoints().getAsJsonObject("authorize").get("method").getAsString();

        this.authenticator = new Auth(config.getOptions(), authenticateMethod, authenticateRoute, cert);

        String url = config.getOptions().get("baseUri") + route;
        URL link = new URL(url);

        if (config.getOptions().containsKey("certificadoPix")) {
            HttpsURLConnection client = (HttpsURLConnection) link.openConnection();
            client.setSSLSocketFactory(
                    this.addCert((cert.open((String) config.getOptions().get("certificadoPix")))).getSocketFactory());
            this.requester = new Request(method, client);

        } else {
            HttpURLConnection client = (HttpsURLConnection) link.openConnection();
            this.requester = new Request(method, client);
        }

        if (config.getOptions().containsKey("partnerToken")) {
            this.requester.addHeader("partner-token", (String) config.getOptions().get("partnerToken"));
        }

        if (config.getOptions().containsKey("headers")) {
            this.requester.addHeader("x-skip-mtls-checking", (String) config.getOptions().get("headers"));
        }

        this.body = body;
    }

    public JsonObject send() throws AuthorizationException, GerencianetException, IOException {

        Date expiredDate = this.authenticator.getExpires();

        if (this.authenticator.getExpires() == null || expiredDate.compareTo(new Date()) <= 0) {
            this.authenticator.authorize();
        }

        this.requester.addHeader("Authorization", "Bearer " + this.authenticator.getAccessToken());

        try {
            return this.requester.send(this.body);
        } catch (AuthorizationException e) {
            this.authenticator.authorize();
            return this.requester.send(body);
        }
    }


    private SSLContext addCert(InputStream keyStoreData) throws Exception {
        KeyStore clientStore = KeyStore.getInstance("PKCS12");
        clientStore.load(keyStoreData, "".toCharArray());
        KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
        kmf.init(clientStore, "".toCharArray());
        SSLContext sslContext = SSLContext.getInstance("TLS");
        sslContext.init(kmf.getKeyManagers(), null, new SecureRandom());
        return sslContext;
    }
}

@@ -80,36 +80,8 @@
 r;%0A%0A
-import java.io.IOException;%0A
 impo
@@ -474,79 +474,8 @@
 ion;
-%0Aimport br.com.gerencianet.sdk.android.exceptions.GerencianetException;
 %0A%0Apu
@@ -547,22 +547,16 @@
 private 
-final 
 Auth aut
@@ -601,16 +601,175 @@
 ct body;
+%0A    private final Config config;%0A    private final String authenticateRoute;%0A    private final String authenticateMethod;%0A    private final AssetManager cert;
 %0A%0A    pu
@@ -883,39 +883,67 @@
 ption %7B%0A        
-String 
+this.config = config;%0A        this.
 authenticateRout
@@ -938,21 +938,22 @@
 enticate
-Route
+Method
  = confi
@@ -1003,21 +1003,22 @@
 %22).get(%22
-route
+method
 %22).getAs
@@ -1035,23 +1035,21 @@
         
-String 
+this.
 authenti
@@ -1044,38 +1044,37 @@
 his.authenticate
-Method
+Route
  = config.getEnd
@@ -1108,38 +1108,37 @@
 uthorize%22).get(%22
-method
+route
 %22).getAsString()
@@ -1135,25 +1135,24 @@
 AsString();%0A
-%0A
         this
@@ -1156,97 +1156,39 @@
 his.
-authenticator = new Auth(config.getOptions(), authenticateMethod, authenticateRoute, cert
+cert = cert;%0A        this.auth(
 );%0A%0A
@@ -1882,18 +1882,16 @@
 Token%22))
- %7B
 %0A       
@@ -1984,35 +1984,24 @@
 erToken%22));%0A
-        %7D%0A%0A
         if (
@@ -2043,18 +2043,16 @@
 aders%22))
- %7B
 %0A       
@@ -2151,25 +2151,16 @@
 ers%22));%0A
-        %7D
 %0A%0A      
@@ -2201,81 +2201,187 @@
 lic 
-JsonObject send() throws AuthorizationException, GerencianetException, IO
+void auth() throws Exception %7B%0A        this.authenticator = new Auth(config.getOptions(), authenticateMethod, authenticateRoute, cert);%0A    %7D%0A%0A    public JsonObject send() throws 
 Exce
@@ -2809,24 +2809,49 @@
 eption e) %7B%0A
+            this.auth();%0A
             

fix auth