package ibase.utility.training;

import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.StringReader;
import java.rmi.RemoteException;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.HashMap;

import javax.json.Json;
import javax.json.JsonObject;
import javax.json.JsonReader;

import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import com.jcraft.jsch.ChannelSftp;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.JSchException;
import com.jcraft.jsch.Session;
import com.jcraft.jsch.SftpException;

import ibase.scheduler.utility.interfaces.Schedule;
import ibase.utility.BaseLogger;
import ibase.utility.E12GenericUtility;
import ibase.utility.UserInfoBean;
import ibase.webitm.ejb.ActionHandlerEJB;
import ibase.webitm.ejb.DBAccessEJB;
import ibase.webitm.utility.ITMException;

public class ScheduledSFTPUploader implements Schedule {
	E12GenericUtility e12GenericUtility = new E12GenericUtility();
	UserInfoBean userInfoGlobal = new UserInfoBean();
	DBAccessEJB dbAccessEJB = new DBAccessEJB();
	NodeList argNodeList = null;
	boolean Bankcodetobool = false;
	String BankCode = "";

	ActionHandlerEJB actionHandlerEJB = new ActionHandlerEJB();

	String payIntArgsStr = "";

	JsonObject payIntArgsJSON = parseJsonString(payIntArgsStr);

	// get values from json

	String bankIntegrationXMLFolderPath = getValueFromJson(payIntArgsJSON, "bank_specific_xml_folder");

	public static JsonObject parseJsonString(String jsonString) {
		JsonReader jsonReader = Json.createReader(new StringReader(jsonString));
		return jsonReader.readObject();
	}

	// Method to convert a JSON string to a JsonObject
	public static String getValueFromJson(JsonObject jsonObject, String key) {
		if (jsonObject.containsKey(key)) {
			return jsonObject.getString(key);
		} else {
			return null; // or throw an exception, handle accordingly
		}
	}

	@Override
	public String schedule(HashMap arg0) throws Exception {
		return null;
	}

	@Override
	public String schedule(String name) throws Exception {
		BaseLogger.log("2", null, null, "ScheduledSFTPUploader calling------------------");
		BaseLogger.log("3", null, null, "name::[ " + name + " ]");

		Document schdulerInfoDocument = e12GenericUtility.parseString(name);
		UserInfoBean userInfo = new UserInfoBean(e12GenericUtility.serializeDom(
				schdulerInfoDocument.getElementsByTagName("USERINFOXML").item(0).getChildNodes().item(0)));
		userInfoGlobal = userInfo;
		argNodeList = schdulerInfoDocument.getElementsByTagName("ACTUALPARAMETER");

		for (int i = 0; i < argNodeList.getLength(); i++) {
			Node childNode = argNodeList.item(i);
			if (childNode.getNodeType() != Node.ELEMENT_NODE) {
				continue;
			}
			if (childNode != null) {
				System.out.println("childNode=[" + childNode + "]");
				Bankcodetobool = isParameterPresent(childNode, "Bank_Code");

				if (Bankcodetobool) {
					if (childNode.getAttributes().getNamedItem("name").getNodeValue().equalsIgnoreCase("Bank_Code")) {
						BankCode = E12GenericUtility.checkNull(childNode.getFirstChild().getNodeValue());
						System.out.println("BankCode = [" + BankCode + "]");
					}
				}
			}

			scheduledSFTPUploading(userInfo, BankCode);
		}

		return null;
	}

	@Override
	public String schedulePriority(String arg0) throws Exception {
		// TODO Auto-generated method stub
		return null;
	}

	private boolean isParameterPresent(Node childNode, String attribName) throws ITMException {
		boolean attribFound = false;
		try {
			System.out.println("attribFound test= [" + childNode.getAttributes() + "]");
			if (childNode != null && childNode.getAttributes() != null) {
				System.out.println(
						"attribFound name= [" + childNode.getAttributes().getNamedItem("name").getNodeValue() + "]");
				if (childNode.getAttributes().getNamedItem("name").getNodeValue().equalsIgnoreCase(attribName)) {
					attribFound = true;
				}
			}

		} catch (Exception e) {
			throw new ITMException(e);
		}
		System.out.println("attribFound = [" + attribFound + "]");
		return attribFound;
	}

	public void scheduledSFTPUploading(UserInfoBean userInfo, String bankCode) {

		String payIntArgs = "";

		try {
			payIntArgs = dbAccessEJB.getDBColumnValue("BANK", "PAY_INT_ARGS", "BANK_CODE  = '" + bankCode + "'",
					userInfo.getTransDB());
			BaseLogger.log("3", null, null, "Value of payIntArgs... [" + payIntArgs + "]");

		} catch (RemoteException | ITMException e) {
			e.printStackTrace();
		}
	}

	public static void uploadFile(String bankIntegrationXMLFolderPath, String remoteFilePath,
			JsonObject payIntArgsJSON) {
		
		final String username = payIntArgsJSON.getString("username");
		final String hostName = payIntArgsJSON.getString("host_name");
		final int port = Integer.parseInt(payIntArgsJSON.getString("port"));
		final String privatekeyfilePath = payIntArgsJSON.getString("private_key_file_path");
		final String privatekeyfilename = payIntArgsJSON.getString("private_key_file_name");

		JSch jsch = new JSch();

		Session session = null;
		ChannelSftp channelSftp = null;
		InputStream inputStream = null;

		try {
			jsch.addIdentity(privatekeyfilePath);

			session = jsch.getSession(username, hostName, port);
			session.setConfig("StrictHostKeyChecking", "no");
			session.connect();

			channelSftp = (ChannelSftp) session.openChannel("sftp");
			channelSftp.connect();

			// Create the remote directory if it doesn't exist
			String remoteDirectory = remoteFilePath.substring(0, remoteFilePath.lastIndexOf("/"));
			createRemoteDirectory(channelSftp, remoteDirectory);

			inputStream = new FileInputStream(bankIntegrationXMLFolderPath);

			channelSftp.put(inputStream, remoteFilePath);

			System.out.println("File uploaded successfully.");
		} catch (JSchException | SftpException | java.io.IOException e) {
			e.printStackTrace();
		} finally {
			if (inputStream != null) {
				try {
					inputStream.close();
				} catch (java.io.IOException e) {
					e.printStackTrace();
				}
			}
			if (channelSftp != null && channelSftp.isConnected()) {
				channelSftp.disconnect();
			}
			if (session != null && session.isConnected()) {
				session.disconnect();
			}
		}
	}

	/*
	// Create new file archive if not present
	private static void moveFileToArchive(File file) {
		// Create the archive directory if it doesn't exist
		File archiveDir = new File(LOCAL_DIRECTORY + File.separator + ARCHIVE_DIRECTORY);
		if (!archiveDir.exists()) {
			archiveDir.mkdir();
			System.out.println("Archive directory created: " + archiveDir.getAbsolutePath());
		}

		// Move the file to the archive directory
		File destFile = new File(archiveDir.getAbsolutePath() + File.separator + file.getName());
		if (file.renameTo(destFile)) {
			System.out.println("File moved to archive: " + destFile.getAbsolutePath());
		} else {
			System.out.println("Failed to move file to archive.");
		}
	}
	*/

	private static void createRemoteDirectory(ChannelSftp channelSftp, String directory) throws SftpException {
		try {
			channelSftp.cd(directory);
		} catch (SftpException e) {
			// Directory does not exist, so create it
			String[] dirs = directory.split("/");
			for (String dir : dirs) {
				if (dir.length() > 0) {
					try {
						channelSftp.cd(dir);
					} catch (SftpException ex) {
						channelSftp.mkdir(dir);
						channelSftp.cd(dir);
					}
				}
			}
		}
	}

}
