package org.bdware.sc.boundry.utils;

import org.bdware.sc.ContractProcess;
import org.bdware.sc.compiler.PermissionStub;
import org.bdware.sc.node.Permission;

import java.lang.reflect.Method;
import java.sql.Connection;
import java.util.Properties;

@PermissionStub(permission = Permission.SQL)
public class SQLUtil {
    public static void initDriver(String driver) {
        try {
            Thread.currentThread()
                    .setContextClassLoader(ContractProcess.instance.engine.getClassLoad());
            Class.forName(driver, true, ContractProcess.instance.engine.getClassLoad());
        } catch (Exception e) {
            System.out.println(
                    "Still can't find class! Cl of SQLUtil:\n\t\t"
                            + SQLUtil.class.getClassLoader());
            System.out.println(
                    "Cl of DEgine:\n\t\t" + ContractProcess.instance.engine.getClassLoad());
            e.printStackTrace();
        }
    }

    public static Connection getConnection(String url, String user, String password) {
        try {
            Thread.currentThread()
                    .setContextClassLoader(ContractProcess.instance.engine.getClassLoad());
            if (!url.startsWith("jdbc")) {
                url += "jdbc:mysql://";
            }
            java.util.Properties info = new java.util.Properties();

            if (user != null && !"undefined".equals(user)) {
                info.put("user", user);
            }
            if (password != null && !"undefined".equals(password)) {
                info.put("password", password);
            }
            if (url.startsWith("jdbc:postgresql")) info.put("sslmode", "allow");

            Class<?> clz =
                    Class.forName(
                            "java.sql.DriverManager",
                            true,
                            ContractProcess.instance.engine.getClassLoad());
            // set caller class into null, thus use YJSClassLoader in
            // DriverManager.isDriverAllowed(driver,classloader);
            Method m =
                    clz.getDeclaredMethod(
                            "getConnection", String.class, Properties.class, Class.class);
            m.setAccessible(true);
            return (Connection) m.invoke(null, url, info, null);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
}
