using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using System.Data.SqlClient;    // SqlConnection
using Oracle.ManagedDataAccess.Client;
using System.Data;              // DataTable

namespace Post
{
    public class ConvertQuery
    {
        #region ConvertDdlQuery() : create ddl query
        public string ConvertDdlQuery(string type, List<Struct.TracingRecordDataDefinition> tracingDefinitionDataList)
        {
            Console.WriteLine("++++++++++++++++++ConvertDdlQuery start++++++++++++++++++");
            ConstValuesTracing constValuesTracing = new ConstValuesTracing();
            ConstValues constValues = new ConstValues();
            StringBuilder sbColumn = new StringBuilder();

            string commandList = "";
            string tableName = tracingDefinitionDataList[0].table_def.table_name;
            string convertType = "";
            string convertPk = "";
            string convertNull = "";

            Console.WriteLine("tableName : " + tableName);

            Console.WriteLine("tracingDefinitionDataList cnt : " + tracingDefinitionDataList.Count);
            Console.WriteLine("column_def cnt : " + tracingDefinitionDataList[0].column_def.Count);
            for (int i = 0; i < tracingDefinitionDataList[0].column_def.Count; i++)
            {
                byte dataType = tracingDefinitionDataList[0].column_def[i].datatype;

                if (tracingDefinitionDataList[0].column_def[i].key_column == 1)
                {
                    convertPk = "PRIMARY KEY";
                }
                else
                {
                    convertPk = "";
                }

                if (tracingDefinitionDataList[0].column_def[i].is_nullable == 1)
                {
                    convertNull = "NULL";
                }
                else
                {
                    convertNull = "NOT NULL";
                }

                if (type.Equals(constValues.CONST_DBTYPE_ORACLE, StringComparison.OrdinalIgnoreCase))
                {
                    if (dataType == constValuesTracing.CONST_COL_TYPE_STRING)   // 32
                    {
                        convertType = constValuesTracing.CONST_TRACING_TABLEMETA_DATATYPE_VARCHAR2;
                    }
                    else if (dataType == constValuesTracing.CONST_COL_TYPE_NUMERIC)   // 16
                    {
                        convertType = constValuesTracing.CONST_TRACING_TABLEMETA_DATATYPE_NUMBER;
                    }
                }
                else if (type.Equals(constValues.CONST_DBTYPE_MSSQL, StringComparison.OrdinalIgnoreCase))
                {
                    if (dataType == constValuesTracing.CONST_COL_TYPE_STRING)   // 32
                    {
                        convertType = constValuesTracing.CONST_TRACING_TABLEMETA_DATATYPE_VARCHAR;
                    }
                    else if (dataType == constValuesTracing.CONST_COL_TYPE_NUMERIC)   // 16
                    {
                        //convertType = constValuesTracing.CONST_TRACING_TABLEMETA_DATATYPE_INT;
                        convertType = constValuesTracing.CONST_TRACING_TABLEMETA_DATATYPE_NUMERIC;
                    }
                }

                //Console.WriteLine("name :: " + tracingDefinitionDataList[0].column_def[i].name);
                //Console.WriteLine("convertType :: " + convertType);
                //Console.WriteLine("extern_length :: " + tracingDefinitionDataList[0].column_def[i].extern_length);
                //Console.WriteLine("convert key_column :: " + convertPk);
                //Console.WriteLine("convert is_nullable :: " + convertNull);
                //Console.WriteLine("---------------------------------------");

                if (i == 0)
                {
                    sbColumn.Append(String.Format("{0} {1}({2}) {3} {4}", tracingDefinitionDataList[0].column_def[i].name, convertType, tracingDefinitionDataList[0].column_def[i].extern_length, convertPk, convertNull));
                }
                else
                {
                    sbColumn.Append(String.Format(", {0} {1}({2}) {3} {4}", tracingDefinitionDataList[0].column_def[i].name, convertType, tracingDefinitionDataList[0].column_def[i].extern_length, convertPk, convertNull));
                }
            }


            commandList = String.Format("create table {0} ({1})", tableName, sbColumn.ToString());
            Console.WriteLine("++++++++++++++++++ConvertDdlQuery end++++++++++++++++++");
            return commandList;
        }
        #endregion

        #region ConvertDmlQuery() : create dml query
        public List<string> ConvertDmlQuery(string type, List<Struct.TraceDml> tracingRecordDmlList, List<ConstStruct.MetaInfo> metaInfoList, List<Struct.TracingRecordDataDefinition> tracingDefinitionDataList, Object conn)
        {
            Console.WriteLine("##### ConvertDmlQuery #####");
            ProcessDatabase processDatabase = new ProcessDatabase(type);
            ConstValues constValues = new ConstValues();

            List<string> commandList = new List<string>();
            List<Struct.TracingRecordDml> recordList = new List<Struct.TracingRecordDml>();
            List<ConstStruct.MetaDefInfo> metaDefList = new List<ConstStruct.MetaDefInfo>();
            List<ConstStruct.ParameterOrderInfo> parameterOrderInfoList = new List<ConstStruct.ParameterOrderInfo>();    // parameter 매핑 순서 정보 리스트                                    

            ExecuteOracleDatabase executeOrcl;
            ExecuteSqlserverDatabase executeSqlserver;

            try
            {
                for (int i = 0; i < tracingRecordDmlList.Count; i++)
                {
                    for(int j = 0; j < tracingRecordDmlList[i].tracingRecordList.Count; j++)
                    {
                        string colNames = "";
                        string colValues = "";
                        bool temp = true;

                        // get metainfo
                        DataTable metaInfo = processDatabase.GetMetaInfo(metaInfoList, tracingRecordDmlList[i].schema, tracingRecordDmlList[i].object_n);
                        // get record list
                        recordList.Add(tracingRecordDmlList[i].tracingRecordList[j]);

                        // get meta def list
                        metaDefList = processDatabase.GetMetaDefList(recordList[0].header.schema, recordList[0].header.object_n, metaInfo, tracingDefinitionDataList);
                        processDatabase.GetInsertColNameFromRecord(recordList[0], metaDefList, ref colNames, ref colValues, ref parameterOrderInfoList);

                        Console.WriteLine("colNames : " + colNames);
                        Console.WriteLine("parameterOrderInfoList : " + parameterOrderInfoList.Count);

                        string query = String.Format("INSERT INTO {0}.{1} ({2}) VALUES ({3})", tracingRecordDmlList[i].schema, tracingRecordDmlList[i].object_n, colNames, colValues);
                        Console.WriteLine("query :: " + query);

                        DataTable dtParameter = processDatabase.GetParameterDataTable(parameterOrderInfoList, recordList.Count);

                        if (type.Equals(constValues.CONST_DBTYPE_ORACLE, StringComparison.OrdinalIgnoreCase))
                        {
                            OracleConnection orclConn = (OracleConnection)conn;
                            executeOrcl = new ExecuteOracleDatabase(orclConn);
                        }
                        else if (type.Equals(constValues.CONST_DBTYPE_MSSQL, StringComparison.OrdinalIgnoreCase))
                        {
                            SqlConnection sqlConn = (SqlConnection)conn;
                            executeSqlserver = new ExecuteSqlserverDatabase(sqlConn);
                            SqlCommand cmd = new SqlCommand();

                            executeSqlserver.SetParameters(ref cmd, ref dtParameter, recordList, metaDefList, parameterOrderInfoList);

                            temp = executeSqlserver.AddWithValueForSqlcommand(ref cmd, parameterOrderInfoList, dtParameter, query, recordList);

                            cmd.Dispose();
                        }
                        Console.WriteLine("bool temp : " + temp);

                    }
                }
            } catch(Exception e)
            {
                Console.WriteLine("convert dml : " + e.ToString());
                return null;
            }

            return commandList;
        }
        #endregion
    }
}
