package geisplugin;

import java.awt.Desktop;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.URL;
import java.net.URLClassLoader;
import java.sql.Connection;
import java.sql.Driver;
import java.sql.DriverManager;
import java.sql.DriverPropertyInfo;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.SQLFeatureNotSupportedException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import java.util.logging.Logger;

import javax.swing.JOptionPane;

import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.Platform;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.internal.core.PackageFragmentRoot;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.ui.PlatformUI;

/**
 * DE: 
 *
 * EN: 
 * 
 * 
 * Program changes
 * **************************************************************************************
 * Date			* Ticket	* KonzFirm	* Responsible	* programmer    *
 * Change										*
 * **************************************************************************************
 *
 * @author huellmante
 * @version 1.0
 *
 */

//Cp1252 -> Default Eclipse Sourceencoding

@SuppressWarnings("restriction")
public abstract class Tools {
	
	public static final String[] getDBs() {
		Connection jdbc = null;
		Statement stmt = null;
		ResultSet rs = null;
		try {
			jdbc = getConnection();
			stmt = jdbc.createStatement();
			rs = stmt.executeQuery("SELECT TABLE_SCHEM||' - '||IFNULL(SCHEMA_TEXT, '') FROM SYSIBM.SQLSCHEMAS WHERE TABLE_CAT='GEISAS01'");
			final ArrayList<String> localDBList = new ArrayList<String>(512);
			while (rs.next()) {
				localDBList.add(rs.getString(1));
			}
			return localDBList.toArray(new String[0]);
		} catch (final Exception e) {
			e.printStackTrace();
		} finally {
			if (rs != null) {
				try {
					rs.close();
				} catch (final Exception e) {
					e.printStackTrace();
				}
				rs = null;
			}
			if (stmt != null) {
				try {
					stmt.close();
				} catch (final Exception e) {
					e.printStackTrace();
				}
				stmt = null;
			}
		}
		return new String[0];
	}
	
	public final static String[] getTables(final String db) {
		Connection jdbc = null;
		Statement stmt = null;
		ResultSet rs = null;
		try {
			jdbc = Tools.getConnection();
			stmt = jdbc.createStatement(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY);
			rs = stmt.executeQuery("SELECT DISTINCT RTRIM(a.table_name)||' - '||b.TABLE_TEXT as a FROM sysibm.SQLColumns a INNER JOIN qsys2.systables b ON a.table_name = b.table_name AND a.table_schem = b.table_schema WHERE b.type != 'A' AND a.table_schem='" + db + "' AND b.table_schema='" + db + "' ORDER BY a");
			final ArrayList<String> localTableList = new ArrayList<String>(512);
			while (rs.next()) {
				localTableList.add(rs.getString(1));
			}
			return localTableList.toArray(new String[0]);
		} catch (final Exception e) {
			e.printStackTrace();
		} finally {
			if (rs != null) {
				try {
					rs.close();
				} catch (final Exception e) {
					e.printStackTrace();
				}
				rs = null;
			}
			if (stmt != null) {
				try {
					stmt.close();
				} catch (final Exception e) {
					e.printStackTrace();
				}
				stmt = null;
			}
		}
		return new String[0];
	}
	
	private static class DriverShim implements Driver {
		private Driver driver;
		private DriverShim(final Driver d) {
			this.driver = d;
		}
		@Override
		public boolean acceptsURL(final String u) throws SQLException {
			return this.driver.acceptsURL(u);
		}
		@Override
		public Connection connect(final String u, final Properties p) throws SQLException {
			return this.driver.connect(u, p);
		}
		@Override
		public int getMajorVersion() {
			return this.driver.getMajorVersion();
		}
		@Override
		public int getMinorVersion() {
			return this.driver.getMinorVersion();
		}
		@Override
		public DriverPropertyInfo[] getPropertyInfo(final String u, final Properties p) throws SQLException {
			return this.driver.getPropertyInfo(u, p);
		}
		@Override
		public boolean jdbcCompliant() {
			return this.driver.jdbcCompliant();
		}
		@Override
		public Logger getParentLogger() throws SQLFeatureNotSupportedException {
			return null;
		}
	}

	private static String getjt400Url() throws Exception {
		final List<String> pathList = new ArrayList<String>(17);
		pathList.add("C:/EnterpriseClient/tools/embeddedserver/webapps/editor/WEB-INF/lib/jt400.jar");
		pathList.add("C:/EnterpriseClient/server/tomcattools/webapps/editor/WEB-INF/lib/jt400.jar");
		pathList.add("C:/Program Files (x86)/Eclipse/jt400.jar");
		pathList.add("C:/Program Files/Eclipse/jt400.jar");
		pathList.add("C:/Program Files (x86)/Eclipse/plugins/jt400.jar");
		pathList.add("C:/Program Files/Eclipse/plugins/jt400.jar");
		pathList.add("C:/Users/"+ System.getProperty("user.name") + "/.razorsql/jtopen/jt400.jar");
		pathList.add("C:/Program Files (x86)/Argus/embeddedserver/webapps/argus_page/WEB-INF/lib/jt400.jar");
		pathList.add("C:/Program Files (x86)/ArgusTest/embeddedserver/webapps/argus_page/WEB-INF/lib/jt400.jar");
		pathList.add("C:/Program Files/Argus/embeddedserver/webapps/argus_page/WEB-INF/lib/jt400.jar");
		pathList.add("C:/Program Files/ArgusTest/embeddedserver/webapps/argus_page/WEB-INF/lib/jt400.jar");
		pathList.add("C:/Program Files/Argus/embeddedserver/webapps/argus_page/WEB-INF/lib/jt400.jar");

		if (Platform.isRunning()) {
			pathList.add((Platform.getInstallLocation().getURL().toString()+"jt400.jar").substring(6));
			pathList.add((Platform.getInstallLocation().getURL().toString()+"plugins/jt400.jar").substring(6));
		}
		
		pathList.add("C:/projects/argus_page_entw/webcontent/WEB-INF/lib/jt400.jar");
		pathList.add("C:/Program Files (x86)/IBM/Client Access/jt400/lib/jt400.jar");
		pathList.add("C:/Program Files/IBM/Client Access/jt400/lib/jt400.jar");

		int i = 0;
		for(; i != pathList.size(); ++i) {
			if(new File(pathList.get(i)).exists()) {
				return "file:/" + pathList.get(i);
			}
		}
		
		throw new Exception("Can't find the jt400.jar driver");
	}
	
	static private final String user = "SVCJOBI";//argus  GCC2TST
	static private final String password = "pw_8e0#164";//argus369   GCC2369

	static private boolean driverLoaded = false;
	
	public static Connection con = null;
	
	public static Connection getConnection() throws Exception {
		if(!driverLoaded) {
			DriverManager.registerDriver((new DriverShim( ((Driver)Class.forName("com.ibm.as400.access.AS400JDBCDriver", true, new URLClassLoader(new URL[] { new URL(getjt400Url()) })).newInstance()))));
			driverLoaded = true;
		}
		if (con == null || con.isClosed()) {
			con = DriverManager.getConnection("jdbc:as400://as400/GEISDB01;metadata source=0;translate binary=true;naming=system", user, password);
			con.setReadOnly(true);
			con.setAutoCommit(false);
		}
		return con;
	}

	public static String read(final String filename) throws IOException {
		final StringBuilder text = new StringBuilder();
		final char[] buffer = new char[0xFFFF];

		InputStreamReader reader = new InputStreamReader(new FileInputStream(new File(filename)), "Cp1252");
		try {
			int len = 0;
			while ((len = reader.read(buffer)) != -1) {
				text.append(buffer, 0, len);
			}
		} finally {
			reader.close();
		}
		return text.toString();
	}

	public static void write(final String filename, final String text) throws IOException {
		if(filename==null || filename.equals("nullnull"))
			return;

		String folderName = filename;

		if(folderName.endsWith(".xml") || folderName.endsWith(".java")) {
			folderName = folderName.substring(0, filename.lastIndexOf('\\'));
		}
		File f = new File(filename);
		try {
			new File(folderName).mkdirs();
		}
		catch(Exception e) {}
		f.createNewFile();
		OutputStreamWriter writer = new OutputStreamWriter(new FileOutputStream(f), "Cp1252");
		try {
			writer.write(text);
			writer.flush();
		} finally {
			writer.close();
		}
	}
	
	public static String readUTF8(final String filename) throws IOException {
		final StringBuilder text = new StringBuilder();
		final char[] buffer = new char[0xFFFF];

		InputStreamReader reader = new InputStreamReader(new FileInputStream(new File(filename)), "UTF-8");
		try {
			int len = 0;
			while ((len = reader.read(buffer)) != -1) {
				text.append(buffer, 0, len);
			}
		} finally {
			reader.close();
		}
		return text.toString();
	}

	public static void writeUTF8withFolderCreation(final String filename, final String text) throws IOException {
		if(filename==null || filename.equals("nullnull"))
			return;

		String folderName = filename;

		if(folderName.endsWith(".xml") || folderName.endsWith(".java")) {
			folderName = folderName.substring(0, filename.lastIndexOf('\\'));
		}
		File f = new File(filename);
		try {
			new File(folderName).mkdirs();
		}
		catch(Exception e) {}
		f.createNewFile();
		OutputStreamWriter writer = new OutputStreamWriter(new FileOutputStream(f), "UTF-8");
		try {
			writer.write(text);
			writer.flush();
		} finally {
			writer.close();
		}
	}

	public static void writeUTF8(final String filename, final String text) throws IOException {
		if(filename==null || filename.equals("nullnull"))
			return;
		File f = new File(filename);
		f.createNewFile();
		OutputStreamWriter writer = new OutputStreamWriter(new FileOutputStream(f), "UTF-8");
		try {
			writer.write(text);
			writer.flush();
		} finally {
			writer.close();
		}
	}

	public static void writeNoPathCreation(final String filename, final String text) throws IOException {
		File f = new File(filename);
		f.createNewFile();
		OutputStreamWriter writer = new OutputStreamWriter(new FileOutputStream(f), "Cp1252");
		try {
			writer.write(text);
			writer.flush();
		} finally {
			writer.close();
		}
	}

	public static IProject getCurrentSelectedProject() throws Exception {
		
	    IProject project = null;
	    
		if (Platform.isRunning()) {
		    ISelection selection = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getSelectionService().getSelection();
	
		    if(selection instanceof IStructuredSelection) {
		        Object element = ((IStructuredSelection)selection).getFirstElement();
	
		        if (element instanceof IResource) {
		            project= ((IResource)element).getProject();
		        } else if (element instanceof PackageFragmentRoot) {
		            IJavaProject jProject = ((PackageFragmentRoot)element).getJavaProject();
		            project = jProject.getProject();
		        } else if (element instanceof IJavaElement) {
		            IJavaProject jProject= ((IJavaElement)element).getJavaProject();
		            project = jProject.getProject();
		        }
		    }
	    }
	    return project;
	}

	public static String trimEnd(final String source) {
	    int pos = source.length() - 1;
	    while ((pos >= 0) && Character.isWhitespace((int) source.charAt(pos))) {
	        pos--;
	    }
	    pos++;
	    return (pos < source.length()) ? source.substring(0, pos) : source;
	}
	
	
	//UPDATE GEISDTA.GXPADAT SET PAKEY1 = '2.9', PATXT = '\\nesfs001\install$\Java\Eclipse Plugin\GeisPlugin_2.9.0.jar', PALAED = 09082017, PALAET = 1052 WHERE PAID = 25834;
	public static boolean isNotUpToDate() {
		boolean result = false;
		Connection con = null;
		try {
			con = getConnection();
		} catch (Exception e1) {
			e1.printStackTrace();
			return true;
		}
		try (    
	    	Statement ps = con.createStatement(); 
	    	ResultSet rs = ps.executeQuery("SELECT PAKEY1 from GEISDTA.GXPADAT WHERE PAID=25834 AND PAWERT='GEISPLUGIN'")
	    ) {
    		if (rs.next()) {
    			//System.out.println(new Double(rs.getString(1)));
    			result = (new Double(rs.getString(1)) > 5.0);
    		}

	    } catch (final Exception e) {
	    	e.printStackTrace();
	    }
	    
		if (result) {
	    	if (JOptionPane.showConfirmDialog(Activator.frame, "A Plugin-Update is available, do you want to continue [Yes] or to update [No] ?", "Update", JOptionPane.YES_NO_OPTION) == JOptionPane.YES_OPTION) {
	    		result = false;
	    	} else {
	    		try {
	    			Desktop.getDesktop().open(new File("\\\\nesfs001\\install$\\Java\\Eclipse Plugin"));
	    		} catch (Exception e) {
	    			e.printStackTrace();
	    		}
	    	}
	    }
	    return result;
	}
	
	public static void transform(File source, String srcEncoding, File target, String tgtEncoding) throws IOException {
	    try (
	      BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(source), srcEncoding));
	      BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(target), tgtEncoding)); ) {
	          char[] buffer = new char[16384];
	          int read;
	          while ((read = br.read(buffer)) != -1)
	              bw.write(buffer, 0, read);
	    } 
	}
}
