package ibase.webitm.ejb.sys;

import java.io.BufferedReader;





import java.io.FileReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.Reader;
import java.net.HttpURLConnection;
import java.net.URI;
import java.net.URL;
import java.net.URLEncoder;
//import java.net.http.HttpClient;
//import java.net.http.HttpRequest;
//import java.net.http.HttpResponse;
import java.net.http.*;
import java.nio.charset.StandardCharsets;
import java.rmi.RemoteException;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.X509Certificate;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Collections;
import java.util.Date;
import java.util.Formatter;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Set;

import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;

import org.json.JSONObject;
import org.w3c.dom.Document;

import cdjd.com.fasterxml.jackson.databind.ObjectMapper;
import ibase.ejb.CommonDBAccessEJB;
import ibase.system.config.ConnDriver;
import ibase.utility.BaseLogger;
import ibase.utility.CommonConstants;
import ibase.utility.E12GenericUtility;
import ibase.utility.UserInfoBean;
import ibase.webitm.ejb.ActionHandlerEJB;
import ibase.webitm.ejb.ITMDBAccessEJB;
import ibase.webitm.ejb.ValidatorEJB;
import ibase.webitm.utility.ITMException;

public class RetryAPICall extends ActionHandlerEJB {

	String status = "", callStatus = "", errorString = "", sql = "",
			sql2 = "", sql3 = "", sql4 = "", sql5 = "", token_id = "", enterprise = "",name="",email="",code="",message="", obj_name = "", api_type = "",
			appId = "", ibaseurl = "ibase/rest/EDIService/setData", sysDate = "", responseStr = "", siteCode = "",
			userId = "", time2 = "00:30:00", apiCallTimeStr, responseInfo = "", responseID = "", requestData = "",
			api_Type = "", serviceClass = "", api_Url = "";

	long difference, constantTime = 30, thirtyMins;
	Date apiCallTime = null, currentTime = null, date3 = null, calldate = null;
	ValidatorEJB valEjb = new ValidatorEJB();
	Connection con = null;
	PreparedStatement pstmt = null, pstmt2 = null, pstmt3 = null, pstmt4 = null, pstmt5 = null;
	ResultSet rs = null, rs2 = null, rs3 = null, rs4 = null, rs5 = null;
	HttpServletRequest request = null;
	E12GenericUtility e12genericutility = new E12GenericUtility();
	// DBAccessEJB dbacess = new DBAccessEJB();
	ITMDBAccessEJB itmdbacess = new ITMDBAccessEJB();
	Document dom = null;

	public String actionHandler(String tranId, String xtraParams, String forcedFlag)
			throws RemoteException, ITMException {

		try {

			ConnDriver conndriver = new ConnDriver();
			con = conndriver.getConnectDB("Driver");
			BaseLogger.log("3", null, null, "DANIEL line 61 con: " + con);
			//			 tranId =  request.getParameter("TRAN_ID"); // entry obj_links, link arg column
			// userId = request.getParameter("USER_ID");//get from db and then add it for
			// userinfo below
			// tranId = checkNull(e12genericutility.getColumnValue("tran_id", dom)) ;
			BaseLogger.log("3", null, null, "DANIEL line 71 tranId: " + tranId);
			sql = "SELECT CALL_STATUS,USER_ID FROM API_CALL_LOG WHERE TRAN_ID = ?"; // 000000000002444
			BaseLogger.log("3", null, null, "DANIEL line 70 sql:  " + sql);
			pstmt = con.prepareStatement(sql);
			pstmt.setString(1, tranId);
			rs = pstmt.executeQuery();

			while (rs.next()) {

				status = rs.getString("CALL_STATUS");
				userId = rs.getString("USER_ID");
			}
			BaseLogger.log("3", null, null, "DANIEL line 85 userId:  " + userId);
			BaseLogger.log("3", null, null, "DANIEL line 86 status:  " + status);
			CommonDBAccessEJB commondbacess = new CommonDBAccessEJB();
			UserInfoBean userInfo = commondbacess.createUserInfo(userId);
			BaseLogger.log("3", null, null, "DANIEL line 83 userInfo:  " + userInfo);

			// currentime = getcurrent time here
			// apicalltime = getapicalltime
			// time = currentime-apicalltime
			// time > 30 re call all failed apis inside if

			if (status.equals("F") || status.equals("0")) {

				// getApiDetails
				// how to get failed api details with uri after that to call that particular api
				// thorugh url
				// tranId = request.getParameter("TRAN_ID");
				sql2 = "SELECT CALL_DATE,ENTERPRISE,APP_ID,SITE_CODE,USER_ID,RESPONSE_INFO,RESPONSE_ID,REQUEST_DATA,API_TYPE,API_URL FROM API_CALL_LOG WHERE TRAN_ID = ?"; // or
				// add
				// ?
				BaseLogger.log("3", null, null, "DANIEL line 99 sql2:  " + sql2);
				pstmt2 = con.prepareStatement(sql2);
				pstmt2.setString(1, tranId);
				rs2 = pstmt2.executeQuery();
				int row = rs2.getRow();
				BaseLogger.log("3", null, null, "DANIEL line 111 rs2 row: " + row);
				BaseLogger.log("3", null, null, "DANIEL line 122 rs2: " + rs2);

				while (rs2.next()) {
					// callDate =(Date)checkNull(rs.getDate("CALL_DATE")) ;
					// calldate = rs.getTimestamp("CALL_DATE");
					// on fail get api details to make a url and pass it in http to recall it
					appId = checkNull(rs2.getString("APP_ID"));
					enterprise = checkNull(rs2.getString("ENTERPRISE"));
					siteCode = checkNull(rs2.getString("SITE_CODE"));
					userId = checkNull(rs2.getString("USER_ID"));
					responseInfo = checkNull(rs2.getString("RESPONSE_INFO"));
					responseID = checkNull(rs2.getString("REQUEST_DATA"));
					requestData = checkNull(rs2.getString("REQUEST_DATA"));
					api_Type = checkNull(rs2.getString("API_TYPE"));
					//						api_Url = checkNull(rs.getString("API_URL"));   
					// get api details what details are needed

				}
				BaseLogger.log("3", null, null, "DANIEL line 127 sitecode: " + siteCode);
				BaseLogger.log("3", null, null, "DANIEL line 136 userid rs2: " + userId);
				BaseLogger.log("3", null, null, "DANIEL line 129 responseInfors2: " + responseInfo);
				BaseLogger.log("3", null, null, "DANIEL line 138 appID rs2: " + appId);

				
				sql4 = "SELECT SERVICE_CLASS,OBJ_NAME FROM AUTH_APPS_API WHERE APP_ID = ?";
				BaseLogger.log("3", null, null, "DANIEL line 143 sql4: " + sql4);
				pstmt4 = con.prepareStatement(sql4);
				pstmt4.setString(1, appId);
				rs4 = pstmt4.executeQuery();
				BaseLogger.log("3", null, null, "DANIEL line 147 rs2: " + rs4);

				while (rs4.next()) {

					serviceClass = rs4.getString("SERVICE_CLASS");
					obj_name = rs4.getString("OBJ_NAME");

				}

				BaseLogger.log("3", null, null, "DANIEL line 154 obj_name: " + obj_name);
				BaseLogger.log("3", null, null, "DANIEL line 155 serviceClass: " + serviceClass);
				//String api_url = CommonConstants.EDI_DATA_PATH + File.separator + serviceName + File.separator + enterprise + File.separator + appId + File.separator + dataFileName;

				sql5 = "select token_id from user_acc_channel where app_id = ?";
				pstmt5 = con.prepareStatement(sql5);
				pstmt5.setString(1, appId);
				rs5 = pstmt5.executeQuery();

				if (rs5.next()) {

					token_id = rs5.getString("token_id");
				}
				BaseLogger.log("3", null, null, "DANIEL line 172 token_id: " + token_id);

				api_Url = CommonConstants.TOMCAT_HOME + "/" + ibaseurl + "/" + obj_name + "/" + enterprise + "/" + appId
						+ "/" + serviceClass;
				//http://155.248.250.99:9090/ibase/rest/EDIService/setData/sql_changes/APPVIS/GSBAPP/writeFileSaveTrans
				// api_Url = endpoint;
				BaseLogger.log("3", null, null, "DANIEL line 177 api_Url: " + api_Url);
									
									//String fileName = "demo.txt";
				//					FileReader filereader = new FileReader(fileName);
				//					int i;
				//					while((i=filereader.read()) !=1) 
				//						  {
				//						
				//						System.out.println((char)i);
				//						filereader.close();
				//					}





//	CODE FOR URL
				
				String POST_URL = "http://httpbin.org/post";//https://httpbin.org/post
				String POST_URL2 = "https://fakerestapi.azurewebsites.net/api/v1/Activities";
				String data = "name=DANIEL Q & email=dannyq@gmail & message=hello to post & code=1111";
				String name = "DAniel", code = "1234", email = "danielq@gmail.com", message = "welcome to post";
				String params3 = "name=" +name+ "&email=" +email+ "&message=" +message+ "&code=" +code;
				String requestBody1="{\"name\": \"DANIEL Q\",\"email\": \"danielq@gmail.com\",\"message\": \"welcome to post\"}";
				String requestBody2 = "{\"id\": \"1\",\"completed\": \"true\",\"title\":\"Activity 1\"}";				
				String id="1",title="Activity 1",completed="false";
				String params4 ="id=" +id+ "&title=" +title+ "&completed=" +completed;
			//  String requestBody = "{\"name\": \"John\", \"age\": 30}";	
				BaseLogger.log("3", null, null, "daniel code: "+code);
				BaseLogger.log("3", null, null, "daniel message: "+message);
				BaseLogger.log("3", null, null, "daniel email: "+email);

				//ibase url for testing
//				String chatid="1",otp="12345";
//				String params5="CHATID=" +chatid+ "&OTP="+otp,telegramtoken="bot123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11";
//				String HOST_IP = "http://129.151.46.166:9090";
//				String urlStr = HOST_IP + "/ibase/rest/telegrambot/addUserOtp?chatId=" + chatid + "&otp=" + otp;
//				
				//telegram api for testing
				String namee="Daniel",srname="Quadras",telegramtoken="bot123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11",tChatId="dan123",messagee="Hello to post";
				String params5="Name="+namee+"&SRName="+srname+"&TelegramToken="+telegramtoken;
				String urlStr ="https://api.telegram.org/";
				String urlStr2 = "https://api.telegram.org/bot" + telegramtoken + "/sendMessage";
				String params = "chat_id=" + tChatId + "&text=" + messagee + "&parse_mode=HTML";

				
				
				BaseLogger.log("3", null, null, "DANIEL POST_Url :" + POST_URL);
				boolean isError = false;
				String commErrorMsg = null;
				URL url =null;
				try {

					BaseLogger.log("3", null, null, "daniel dummy url"+POST_URL );
					BaseLogger.log("3", null, null, "daniel INSIDE TRY BLOCK for url" );
					url = new URL(urlStr);//https://fakerestapi.azurewebsites.net/api/v1/Activities  https://httpbin.org/post
					HttpURLConnection con = (HttpURLConnection) url.openConnection();
					con.setConnectTimeout(30000);
					con.setReadTimeout(30000);
					con.setInstanceFollowRedirects(false);
					con.setRequestMethod("POST");
					con.setDoOutput(true);
				    con.setRequestProperty("Content-Type", "application/x-www-form-urlencoded"); //application/x-www-form-urlencoded
					con.setRequestProperty("charset", "utf-8");
				    BaseLogger.log("3", null, null, "daniel  con "+con );
					BaseLogger.log("3", null, null, "daniel URL url: "+url );
					
					OutputStream os= con.getOutputStream();
					BaseLogger.log("3", null, null, "daniel os"+os );
					os.write(params5.getBytes());
					//os.write(requestBody.getBytes()); //os.write(params3.getBytes());
					BaseLogger.log("3", null, null, "DANIEL os getbytes " + os);
					os.flush();
					os.close();
					
					int responseCode = con.getResponseCode();
					BaseLogger.log("3", null, null, "DANIEL responseCode" + responseCode);

					BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()));
					String inputLine = "";
					StringBuffer response = new StringBuffer();

					while ((inputLine = in.readLine()) != null) 
					{
						response.append(inputLine);

					}
					BaseLogger.log("3", null, null, "DANIEL response" + response);
					in.close();
					
					BaseLogger.log("3", null, null, "DANIEL responseCode: " + responseCode);
					BaseLogger.log("3", null, null, "DANIEL response from NEW RESPONSE" + response.toString());
					if (responseCode != HttpURLConnection.HTTP_OK) {
						BaseLogger.log("3", null, null, "DANIEL :: POST request not worked");
						isError = true;
						commErrorMsg = "Post Request Failed";
						isError = false;

					}
					
					errorString = e12genericutility.getErrorString("", "VTROLL", userInfo.getLoginCode());


				} 

				catch (Exception e) {
					e.printStackTrace();
					isError = true;
					commErrorMsg = e.toString();
					BaseLogger.log("3", null, null, "DANIEL exception"+e);
				}
				
				
			}

			else {
				// responseStr = "The Api your trying to recall or retry has not failed";
				errorString = e12genericutility.getErrorString("", "INVALIDKEY", userInfo.getLoginCode());
				BaseLogger.log("3", null, null, "DANIEL line 214 errorString:  " + errorString);

			}

		}

		catch (Exception e) {

			e.printStackTrace();
		}

		finally {

			try {

				if (rs != null) {
					rs.close();
					rs = null;
				}

				if (pstmt != null) {
					pstmt.close();
					pstmt = null;
				}

				if (con != null) {
					con.close();
					con = null;
				}

				if (rs2 != null) {

					rs2.close();
					rs2 = null;
				}

				if (pstmt2 != null) {
					pstmt2.close();
					pstmt2 = null;

				}

				if (rs4 != null) {
					rs4.close();
					rs4 = null;

				}

				if (pstmt4 != null) {
					pstmt4.close();
					pstmt4 = null;

				}

			}

			catch (Exception e) {
				System.out.println(e);
				e.printStackTrace();

			}

		}
		BaseLogger.log("3", null, null, "DANIEL line 251 return errorString" + errorString);
		return errorString;

	}

	public long getDateDifference(String tranId) throws SQLException, ParseException

	{

		SimpleDateFormat sdf = new SimpleDateFormat();
		Calendar cal = Calendar.getInstance();
		BaseLogger.log("3", null, null, "DANIEL line 185 sysdate " + sysDate);
		sysDate = sdf.format(cal.getTime());
		BaseLogger.log("3", null, null, "DANIEL line 187 sysdate " + sysDate);
		date3 = sdf.parse(sysDate);
		BaseLogger.log("3", null, null, "DANIEL line 189 date3 " + date3);

		Formatter formatter = new Formatter();
		formatter.format("%tl:%tM", cal, cal);
		System.out.println(formatter);
		BaseLogger.log("3", null, null, "DANIEL line 194 formatter  " + formatter);
		String datee = formatter.toString();

		BaseLogger.log("3", null, null, "DANIEL line 197 datee  " + datee);
		currentTime = sdf.parse(datee);
		BaseLogger.log("3", null, null, "DANIEL line 199 formatter  " + currentTime);
		long thirtyMins = Long.parseLong(time2);
		BaseLogger.log("3", null, null, "DANIEL line 201 thirtyMins  " + thirtyMins);

		// tranId = request.getParameter("TRAN_ID");
		sql3 = "SELECT TO_CHAR(CALL_DATE,'HH:MI:SS A.M.') FROM API_CALL_LOG WHERE TRAN_ID = ? ";
		BaseLogger.log("3", null, null, "DANIEL line 205 thirtyMins  " + sql3);
		pstmt3 = con.prepareStatement(sql3);
		pstmt.setString(1, tranId);
		rs3 = pstmt.executeQuery();

		while (rs3.next()) {

			apiCallTimeStr = rs.getString("to_char(call_date)"); // how to get this column name
		}
		apiCallTime = sdf.parse(apiCallTimeStr);
		BaseLogger.log("3", null, null, "DANIEL line 216 thirtyMins  " + apiCallTime);
		difference = date3.getTime() - apiCallTime.getTime(); // to figure out how to get apicalltime
		BaseLogger.log("3", null, null, "DANIEL line 218 difference  " + difference);

		try {

			if (rs3 != null) {

				rs3.close();
				rs3 = null;
			}

			if (pstmt3 != null) {
				pstmt3.close();
				pstmt3 = null;

			}

		}

		catch (Exception e) {
			System.out.println(e);
			e.printStackTrace();

		}

		return difference;
	}

	private String checkNull(String input)

	{
		if (input == null) {
			input = "";
		}

		return input;
	}

	
	static SSLContext insecureContext() {
		TrustManager[] noopTrustManager = new TrustManager[] { new X509TrustManager() {
			@Override
			public void checkClientTrusted(X509Certificate[] xcs, String string) {
			}

			@Override
			public void checkServerTrusted(X509Certificate[] xcs, String string) {
			}

			@Override
			public X509Certificate[] getAcceptedIssuers() {
				return null;
			}
		} };

		try {
			SSLContext sc = SSLContext.getInstance("ssl");
			sc.init(null, noopTrustManager, null);
			return sc;
		}

		catch (KeyManagementException | NoSuchAlgorithmException ex) {
		}
		return null;
	}

}
