package com.platform.service;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

import org.apache.log4j.Logger;

import com.base.Custom4exception;
import com.platform.entities.GatherOracleInfo;
import com.platform.entities.OracleConnectorParams;
import com.platform.oracle.OracleConnector;
import com.platform.utils.Configs;
import com.platform.utils.FileOperateHelper;

public class OracleExtractHelper {

	public static Logger log = Logger.getLogger(OracleExtractHelper.class);

	/**
	 * 判断dblink是否已经存在
	 * 
	 * @param conn
	 * @param linkName
	 *            dblink的名称
	 * @return
	 */
	private boolean hasSameNameDBLink(Connection conn, String linkName,
			String filePath) {

		boolean flag = false;
		String sql = "SELECT COUNT(*) c FROM ALL_DB_LINKS WHERE DB_LINK='"
				+ linkName + "'";
		ResultSet rSet = null;
		Statement statement = null;
		try {
			statement = conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,
					ResultSet.CONCUR_UPDATABLE);
			rSet = statement.executeQuery(sql);
			if (rSet.next()) {
				if (rSet.getInt("c") > 0)
					flag = true;
				else
					flag = false;
			}
			FileOperateHelper.fileWrite(filePath + ".log", sql + "\r\n"
					+ "OK \r\n");

		} catch (Exception e) {
			FileOperateHelper.fileWrite(filePath, sql + "\r\n" + e.getMessage()
					+ "\r\n，连接异常！ \r\n");
			log.error(Custom4exception.threadVolume_Oracle_Except, e);
		} finally {
			if (null != statement) {
				try {
					statement.close();
				} catch (SQLException e) {
					log.error(Custom4exception.OracleSQL_Except, e);
				}
			}
		}
		return flag;
	}

	/**
	 * 创建dblink
	 * 
	 * @param conn
	 *            汇总库的连接
	 * @param oc
	 *            采集库 dblink连接参数实体
	 */
	public void createDBLink(Connection conn, OracleConnectorParams oc) {
		String linkName = "LINKTO_J" + oc.getName().replaceAll("-", "_");
		String sql = "CREATE PUBLIC DATABASE LINK "
				+ linkName
				+ " CONNECT TO "
				+ oc.getUser()
				+ " IDENTIFIED BY "
				+ oc.getPassword()
				+ " USING \'(DESCRIPTION =(ADDRESS_LIST =(ADDRESS = (PROTOCOL = TCP)(HOST = "
				+ oc.getIp() + ")(PORT = " + oc.getPort()
				+ ")))(CONNECT_DATA =(SERVICE_NAME =" + oc.getDatabaseName()
				+ ")))\'";
		if (null != oc) {
			if (hasSameNameDBLink(conn, linkName, Configs.EXTRACT_LOG_LOCALTION
					+ oc.getName())) { // 如果dblink已经存在,先删除dblink，在创建dblink
				String deleteSql = "DROP PUBLIC DATABASE LINK " + linkName;
				// 删除 dblink
				if (OracleConnector.execOracleSQL(conn, deleteSql,
						Configs.EXTRACT_LOG_LOCALTION + oc.getName())) {
					if (!OracleConnector.execOracleSQL(conn, sql,
							Configs.EXTRACT_LOG_LOCALTION + oc.getName())) {
						OracleConnector.execUpdateOracleSQL(conn, sql,
								Configs.EXTRACT_LOG_LOCALTION + oc.getName());
					}
				} else {
					Configs.CONSOLE_LOGGER.error("删除已有的DBLink失败,无法创建新的DBLink!");
					FileOperateHelper.fileWrite(Configs.EXTRACT_LOG_LOCALTION
							+ oc.getName() + ".log",
							"删除已有的DBLink失败,无法创建新的DBLink!" + "\r\n");
				}

			} else {
				// 否则，创建dblink
				if (!OracleConnector.execOracleSQL(conn, sql,
						Configs.EXTRACT_LOG_LOCALTION + oc.getName())) {
					OracleConnector.execUpdateOracleSQL(conn, sql,
							Configs.EXTRACT_LOG_LOCALTION + oc.getName());
				}
			}
		}
	}

	/**
	 * 创建表空间
	 * 
	 * @param conn
	 *            汇总库连接
	 * @param collectOracle
	 * @param oc
	 *            汇总库信息
	 * @return
	 */
	public boolean createTableSpace(Connection conn,
			OracleConnectorParams collectOracle, GatherOracleInfo oc) {
		String tmpSql = "select TABLESPACE_NAME from dba_tablespaces where TABLESPACE_NAME = '"
				+ oc.getTableName() + "'";
		// 存在 表空间
		if (OracleConnector.execUpdateOracleSQL(conn, tmpSql,
				Configs.EXTRACT_LOG_LOCALTION + collectOracle.getName())) {
			return true;
		} else {
			String sql = "create tablespace " + oc.getTableName()
					+ " datafile '" + Configs.GATHER_TABLESPACE_PATH
					+ oc.getTableName() + ".dbf"
					+ "' size 512M autoextend on next 512M maxsize unlimited";
			return OracleConnector.execOracleSQL(conn, sql,
					Configs.EXTRACT_LOG_LOCALTION + collectOracle.getName());
		}
	}

	/**
	 * 创建用户并授权
	 * 
	 * @param conn
	 *            汇总库连接
	 * @param oc
	 *            汇总库信息
	 */
	public void createUser(Connection conn, OracleConnectorParams oc,
			GatherOracleInfo totalOracle) {
		String strTUser = "J" + oc.getName().replaceAll("-", "_")
				+ totalOracle.getSuffix();

		String sql = "Create user " + strTUser + " default tablespace "
				+ totalOracle.getTableName() + " identified by "
				+ Configs.GATHER_TABLE_PASSWORD;
		String grantSql = "grant connect, resource, dba to " + strTUser;

		OracleConnector.execOracleSQL(conn, sql, Configs.EXTRACT_LOG_LOCALTION
				+ oc.getName());

		OracleConnector.execOracleSQL(conn, grantSql,
				Configs.EXTRACT_LOG_LOCALTION + oc.getName());
	}

	/**
	 * 创建用户并授权
	 * 
	 * @param conn
	 *            汇总库连接
	 * @param oc
	 *            汇总库信息
	 */
	public void createOnlyUser(Connection conn, OracleConnectorParams oc,
			GatherOracleInfo totalOracle) {
		String strTUser = Configs.GATHER_STANDARD_USER_NAME;

		String sql = "Create user " + strTUser + " default tablespace "
				+ totalOracle.getTableName() + " identified by "
				+ Configs.GATHER_TABLE_PASSWORD;
		String grantSql = "grant connect, resource, dba to " + strTUser;

		OracleConnector.execOracleSQL(conn, sql,
				Configs.EXTRACT_STANDARD_LOG_LOCALTION + oc.getName());

		OracleConnector.execOracleSQL(conn, grantSql,
				Configs.EXTRACT_STANDARD_LOG_LOCALTION + oc.getName());
	}

	/**
	 * 创建用户并授权
	 * 
	 * @param conn
	 *            汇总库连接
	 * @param oc
	 *            汇总库信息
	 */
	public void createTable(Connection conn, OracleConnectorParams oc,
			GatherOracleInfo totalOracle) {
		String strTUser = oc.getName() + totalOracle.getSuffix();

		String sql = "Create table " + strTUser + " default tablespace "
				+ totalOracle.getTableName() + " identified by "
				+ Configs.GATHER_TABLE_PASSWORD;
		String grantSql = "grant connect, resource, dba to " + strTUser;

		OracleConnector.execOracleSQL(conn, sql, Configs.EXTRACT_LOG_LOCALTION
				+ oc.getName());

		OracleConnector.execOracleSQL(conn, grantSql,
				Configs.EXTRACT_LOG_LOCALTION + oc.getName());
	}

	/**
	 * 执行汇总操作
	 * 
	 * @param conn
	 *            汇总库连接
	 * @param oc
	 *            采集库
	 */
	public void extractColleDB(Connection conn, OracleConnectorParams oc,
			GatherOracleInfo totalOracle) {
		String strTUser = "J" + oc.getName().replaceAll("-", "_")
				+ totalOracle.getSuffix();
		String sql = "SELECT 'create table "
				+ strTUser
				+ ".J'|| substr(t.OWNER||'_'||t.TABLE_NAME,0,29)||' as select * from '||t.OWNER||'.'||t.TABLE_NAME||"
				+ "'@LINKTO_J"
				+ oc.getName().replaceAll("-", "_")
				+ ";' FROM dba_tables@LINKTO_J"
				+ oc.getName().replaceAll("-", "_")
				+ " t WHERE t.TABLESPACE_NAME NOT IN ('SYSTEM','SYSAUX')"
				+ " and t.owner||t.table_name not in (select owner||table_name from dba_tables@LINKTO_J"
				+ oc.getName().replaceAll("-", "_")
				+ " where 'data_type'='CLOB')";
		/*
		 * ResultSet rsSet = OracleConnector.getSQLExecResultSet(conn, sql,
		 * Configs.EXTRACT_LOG_LOCALTION + oc.getName());
		 */
		Statement statement = null;
		try {
			statement = conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,
					ResultSet.CONCUR_UPDATABLE);
			ResultSet resultSet = statement.executeQuery(sql);
			FileOperateHelper.fileWrite(
					Configs.EXTRACT_LOG_LOCALTION + oc.getName() + ".log", sql
							+ "\r\n" + "OK \r\n");
			
			while (resultSet.next()) {				
				try {
					String resultSql = resultSet.getString(1).replace(";", "");
					OracleConnector.execUpdateOracleSQL(conn, resultSql,
							Configs.EXTRACT_LOG_LOCALTION + oc.getName());
				} catch (SQLException e) {
					log.error(Custom4exception.threadVolume_Oracle_Except, e);
				}
			}
		} catch (SQLException e) {
			log.error(Custom4exception.threadVolume_Oracle_Except, e);
		}

	}

	/**
	 * 测试是否能否连接上？
	 * 
	 * @return true：能连接上
	 */
	public boolean testConnect(Connection conn) {
		String testSql = "select count(*) from user_tables";
		boolean flag = false;
		try {
			Statement statement = conn.createStatement();
			if (statement.executeUpdate(testSql) > 0)
				flag = true;
		} catch (SQLException e) {
			flag = false;
			log.error(Custom4exception.threadVolume_Oracle_Except, e);
		}
		return flag;
	}

	/**
	 * 执行抽取操作--支付表
	 * 
	 * @param conn
	 *            汇总库连接
	 * @param oc
	 *            采集库
	 */
	public void extractStandardPayTable(Connection conn,
			OracleConnectorParams oc, GatherOracleInfo totalOracle) {
		String strTUser = Configs.GATHER_STANDARD_USER_NAME;
		createPay(conn, oc);
		String sql = "insert into " + strTUser + "."
				+ Configs.GATHER_STANDARD_PAY_TABLE_NAME + " select * from "
				+ strTUser + "." + Configs.GATHER_STANDARD_PAY_TABLE_NAME
				+ "@LINKTOST" + oc.getName();
		String resultSql = sql.replace(";", "");
		OracleConnector.execOracleSQL(conn, resultSql,
				Configs.EXTRACT_STANDARD_LOG_LOCALTION + oc.getName());
	}

	/**
	 * 执行抽取操作--执行表
	 * 
	 * @param conn
	 * @param collectOracle
	 * @param oracleModel
	 */
	public void extractStandardExecTable(Connection conn,
			OracleConnectorParams collectOracle, GatherOracleInfo oracleModel) {
		createExec(conn, collectOracle);
		String strTUser = Configs.GATHER_STANDARD_USER_NAME;

		String sql = "insert into " + strTUser + "."
				+ Configs.GATHER_STANDARD_EXEC_TABLE_NAME + " select * from "
				+ strTUser + "." + Configs.GATHER_STANDARD_EXEC_TABLE_NAME
				+ "@LINKTOST" + collectOracle.getName();
		String resultSql = sql.replace(";", "");
		OracleConnector.execOracleSQL(
				conn,
				resultSql,
				Configs.EXTRACT_STANDARD_LOG_LOCALTION
						+ collectOracle.getName());

	}

	private void createPay(Connection conn, OracleConnectorParams oc) {
		String payCmd = "CREATE TABLE  u_bzbjy.zfxxb(XZQHDM Varchar(255),XZQHMC Varchar(255),PZBH Varchar(255),LYZBKZH Varchar(255),"
				+ "ZFDATE Varchar(255),YSDWCODE Varchar(255),YSDWNAME Varchar(255),YWGKCS Varchar(255),XMCODE Varchar(255),XMNAME Varchar(255),"
				+ "XMLBCODE Varchar(255),XMLBNAME Varchar(255),ZB_NO Varchar(255),GNFLCODE Varchar(255),GNFLNAME Varchar(255),JJFLCODE Varchar(255),"
				+ "JJFLNAME Varchar(255),ZJXZCODE Varchar(255),ZJXZNAME Varchar(255),JSBFFSNAME Varchar(255),SKR Varchar(255),SKRYH Varchar(255),"
				+ "SKRZHZH Varchar(255),FKZHCODE Varchar(255),FKZHNAME Varchar(255),FKYHCODE Varchar(255),FKYHNAME Varchar(255),QSZHCODE Varchar(255),"
				+ "QSZHNAME Varchar(255),QSYHCODE Varchar(255),QSYHNAME Varchar(255),JE Numeric(18,2), SFTK Varchar(255),NIAN Varchar(255),ZY Varchar(255))";

		try {
			OracleConnector.execOracleSQL(conn, payCmd,
					Configs.EXTRACT_STANDARD_LOG_LOCALTION + oc.getName());
		} catch (Exception e) {
			log.error(Custom4exception.threadVolume_Oracle_Except, e);
		}
	}

	/**
	 * 创建dblink
	 * 
	 * @param conn
	 *            汇总库的连接
	 * @param oc
	 *            采集库 dblink连接参数实体
	 */
	public void createStandardDBLink(Connection conn, OracleConnectorParams oc) {
		String linkName = "LINKTOST" + oc.getName();
		String sql = "CREATE PUBLIC DATABASE LINK "
				+ linkName
				+ " CONNECT TO "
				+ oc.getUser()
				+ " IDENTIFIED BY "
				+ oc.getPassword()
				+ " USING \'(DESCRIPTION =(ADDRESS_LIST =(ADDRESS = (PROTOCOL = TCP)(HOST = "
				+ oc.getIp() + ")(PORT = " + oc.getPort()
				+ ")))(CONNECT_DATA =(SERVICE_NAME =" + oc.getDatabaseName()
				+ ")))\'";
		if (null != oc) {
			if (hasSameNameDBLink(conn, linkName,
					Configs.EXTRACT_STANDARD_LOG_LOCALTION + oc.getName()
							+ ".log")) { // 如果dblink已经存在,先删除dblink，在创建dblink
				String deleteSql = "DROP PUBLIC DATABASE LINK " + linkName;
				// 删除 dblink
				if (OracleConnector.execOracleSQL(conn, deleteSql,
						Configs.EXTRACT_STANDARD_LOG_LOCALTION + oc.getName())) {
					// OracleConnector.execOracleSQL(conn, sql,
					// Configs.EXTRACT_STANDARD_LOG_LOCALTION + oc.getName());
					if (!OracleConnector.execOracleSQL(
							conn,
							sql,
							Configs.EXTRACT_STANDARD_LOG_LOCALTION
									+ oc.getName())) {
						OracleConnector.execUpdateOracleSQL(
								conn,
								sql,
								Configs.EXTRACT_STANDARD_LOG_LOCALTION
										+ oc.getName());
					}
				} else {
					Configs.CONSOLE_LOGGER.error("删除已有的DBLink失败,无法创建新的DBLink!");
					FileOperateHelper.fileWrite(
							Configs.EXTRACT_STANDARD_LOG_LOCALTION
									+ oc.getName() + ".log",
							"删除已有的DBLink失败,无法创建新的DBLink!" + "\r\n");
				}

			} else {
				// 否则，创建dblink
				// OracleConnector.execOracleSQL(conn, sql,
				// Configs.EXTRACT_STANDARD_LOG_LOCALTION + oc.getName());
				if (!OracleConnector.execOracleSQL(conn, sql,
						Configs.EXTRACT_STANDARD_LOG_LOCALTION + oc.getName())) {
					OracleConnector.execUpdateOracleSQL(
							conn,
							sql,
							Configs.EXTRACT_STANDARD_LOG_LOCALTION
									+ oc.getName());
				}
			}
		}
	}

	private void createExec(Connection conn, OracleConnectorParams oc) {
		String execCmd = "CREATE TABLE  u_bzbjy.kzxzb(XZQHDM Varchar(255),XZQHMC Varchar(255),YSND Varchar(255),ZBCODE Varchar(255),ZB_ID Varchar(255),ZB_NO Varchar(255),"
				+ "ZBDJLXCODE Varchar(255),ZBDJLXNAME Varchar(255),ZBLXNAME Varchar(255),DOCNO Varchar(255),ZBSM Varchar(255),ZBFWDATE Varchar(255),ZBYSLXCODE Varchar(255),"
				+ "ZBYSLXNAME Varchar(255),ZBYSLYNAME Varchar(255),YSDWCODE Varchar(255),YSDWNAME Varchar(255),GNFLCODE Varchar(255),GNFLNAME Varchar(255),JJFLCODE Varchar(255),"
				+ "JJFLNAME Varchar(255),ZBGLCSNAME Varchar(255),SZGLCODE Varchar(255),SZGLNAME Varchar(255),XMCODE Varchar(255),XMNAME Varchar(255),GZBZ Varchar(255),"
				+ "JJBZ Varchar(255),CGBZ Varchar(255),ZFFSCODE Varchar(255),ZFFSNAME Varchar(255),JZZFBZ Varchar(255),ZBJE Numeric(18,2),ZBTJJE Numeric(18,2),ZBDJJE Numeric(18,2),"
				+ "ZBKYJE Numeric(18,2),ZYZFBZ Varchar(255),BZ Varchar(255))";

		try {
			OracleConnector.execOracleSQL(conn, execCmd,
					Configs.EXTRACT_STANDARD_LOG_LOCALTION + oc.getName());
		} catch (Exception e) {
			log.error(Custom4exception.threadVolume_Oracle_Except, e);
		}
	}
}
