package com.urbancode.util

import java.security.KeyManagementException
import java.security.KeyStoreException
import java.security.NoSuchAlgorithmException
import java.security.cert.CertificateException
import java.security.cert.X509Certificate
import org.apache.http.config.Registry;
import org.apache.http.config.RegistryBuilder;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import javax.net.ssl.HostnameVerifier
import javax.net.ssl.SSLContext
import org.apache.http.conn.socket.ConnectionSocketFactory;
import org.apache.http.conn.socket.PlainConnectionSocketFactory;
import org.apache.http.Header
import org.apache.http.HttpHeaders
import org.apache.http.HttpResponse
import org.apache.http.HttpStatus
import org.apache.http.NameValuePair
import org.apache.http.client.CookieStore
import org.apache.http.client.entity.UrlEncodedFormEntity
import org.apache.http.client.methods.CloseableHttpResponse
import org.apache.http.client.methods.HttpGet
import org.apache.http.client.methods.HttpPost
import org.apache.http.client.methods.HttpRequestBase
import org.apache.http.client.methods.HttpUriRequest
import org.apache.http.client.methods.RequestBuilder
import org.apache.http.client.utils.URIBuilder
import org.apache.http.conn.ssl.SSLConnectionSocketFactory
import org.apache.http.cookie.Cookie
import org.apache.http.entity.StringEntity
import org.apache.http.impl.client.BasicCookieStore
import org.apache.http.impl.client.CloseableHttpClient
import org.apache.http.impl.client.HttpClientBuilder
import org.apache.http.impl.client.LaxRedirectStrategy
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager
import org.apache.http.message.BasicNameValuePair
import org.apache.http.ssl.SSLContextBuilder
import org.apache.http.ssl.TrustStrategy
import org.apache.http.util.EntityUtils
import org.jsoup.Jsoup
import org.jsoup.nodes.Document
import org.jsoup.nodes.Element
import groovy.json.JsonSlurper

 class TokenUtil {
			def CookieStore cleanCookieStore;
			String refreshToken;
			String XSRF_Token;
			def CloseableHttpClient client;

			public CloseableHttpClient getClient() {
			return client;
			}

			public void setClient( CloseableHttpClient client) {
			this.client=client;
			}

			public CookieStore getCleanCookieStore() {
			return cleanCookieStore;
			}

			public void setCleanCookieStore( CookieStore cleanCookieStore) {
			this.cleanCookieStore=cleanCookieStore;
			}

			public String getRefreshToken() {
			return refreshToken;
			}

			public void setRefreshToken( String refreshToken) {
			this.refreshToken=refreshToken;
			}

			public String getXSRF_Token() {
			return XSRF_Token;
			}

			public void setXSRF_Token( String xSRF_Token) {
			XSRF_Token=xSRF_Token;
			}
			
			
			def CloseableHttpClient buildClient()
				throws KeyManagementException, NoSuchAlgorithmException, KeyStoreException 
				{

					SSLContext sslContext=new SSLContextBuilder().loadTrustMaterial(
					new TrustStrategy() {
						public boolean isTrusted( X509Certificate[]chain, String authType) throws CertificateException {
							return true;
						}
					}).build();

			HostnameVerifier hostnameVerifier=NoopHostnameVerifier.INSTANCE;

			SSLConnectionSocketFactory sslSocketFactory=new SSLConnectionSocketFactory(sslContext, hostnameVerifier)
					Registry<ConnectionSocketFactory> socketFactoryRegistry=RegistryBuilder.<ConnectionSocketFactory>create().register("http",PlainConnectionSocketFactory.getSocketFactory()).register("https", sslSocketFactory).build();
					PoolingHttpClientConnectionManager	connMgr=new PoolingHttpClientConnectionManager(socketFactoryRegistry);

					client=HttpClientBuilder.create().setSSLHostnameVerifier(NoopHostnameVerifier.INSTANCE).setSSLContext(sslContext).disableContentCompression().setConnectionManager(connMgr).build();

			return client;
			}

			def getToken( def offlineToken, def serverUrl) {
			
				def parsedJson;
				buildClient();
						HttpPost getTokenMethod = new HttpPost(serverUrl + '/rest/tokens/')
						getTokenMethod.addHeader("Accept", "application/json");
						getTokenMethod.addHeader("Content-Type", "application/x-www-form-urlencoded");
						ArrayList<NameValuePair> postParameters = new ArrayList<NameValuePair>();
						postParameters.add(new BasicNameValuePair("refresh_token", "${offlineToken}"));
				
						getTokenMethod.setEntity(new UrlEncodedFormEntity(postParameters, "UTF-8"));
				
						def resp = client.execute(getTokenMethod);
				
						println (resp.getStatusLine().toString());
				
						def statusCode = resp.getStatusLine().getStatusCode();
						if (statusCode < 200 || statusCode >= 300) {
							println "[Error] Request failed with status ${statusCode}. Exiting Failure.";
							println ('Response:\n' + resp.entity?.content?.getText("UTF-8"));
							System.exit(1);
						}
						def entity = EntityUtils.toString(resp.getEntity());
				
						def slurper = new JsonSlurper();
						try {
							parsedJson = slurper.parseText(entity);
						}
						catch (groovy.json.JsonException e) {
							println "Failed to parse response body. Printing useful debugging information and exiting.";
							println "Response status code: ${statusCode}.";
							println "Header:";
							Header[] headers = resp.getAllHeaders();
							for (Header header : headers) {
								System.out.println(header.getName() + ":"+ header.getValue());
							}
							println "Body:";
							println entity;
							println "Stacktrace:";
							e.printStackTrace();
							System.exit(1);
						}
						return parsedJson
			}

			

}
