using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using MySql.Data.MySqlClient;
using parkMonitor.tools;
using parkMonitor.server.CoreThread;

namespace parkMonitor.Database2
{
    /// <summary>
    /// 数据库操作类
    /// </summary>
    public class DBOperation
    {
        /// <summary>
        /// TIMEOUT超时时间
        /// </summary>
        public const int TIMEOUT = 120000;
        /// <summary>
        /// 查询车库表获得剩余车位数
        /// </summary>
        /// <param name="bq"></param>
        /// <param name="garageID"></param>
        /// <returns></returns>
        public int getGarageFreeSpace(BlockingQueue bq, int garageID)
        {
            MySqlDataReader reader = null;
            int garageFreeSpace = 0;
            string sql = "select * from garage where garageID = '" + garageID + "'";
            Connection conn = CreateConnAndGetValidConn(bq);
            if (conn == null)
            {
                Console.WriteLine("请检查网络！等待网络修复超时");
            }
            else
            {
                try
                {
                    DBAccess access = new DBAccess(sql, conn, CommandTypes.QUERYCOMMAND);
                    object result = access.GetResult();
                    reader = (MySqlDataReader)result;
                    while (reader.Read())
                    {
                        if (reader.HasRows)
                        {
                            garageFreeSpace = reader.GetInt32("garageFreeSpace");
                        }
                        else
                        {
                            Console.WriteLine("车位剩余数查无结果");
                        }
                    }
                    ConnectionPoolManager.ReleaseConnection(conn, bq);
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.Message + "查询剩余车位异常");
                    if (conn != null)
                    {
                        conn.Dispose();
                    }
                    ConnectionPoolManager.AddConnToPooling(1, ConnectionPoolManager.remoteConf);
                }
                finally
                {
                    if (reader != null)
                    {
                        reader.Close();
                        reader.Dispose();
                    }
                }
            }
            return garageFreeSpace; ;
        }
        /// <summary>
        /// 查询所有车位位置及状态
        /// </summary>
        /// <param name="bq"></param>
        /// <param name="garageID"></param>
        /// <returns></returns>
        public Dictionary<int, Parking_Space> GetAllParkingSpace(BlockingQueue bq, int garageID)
        {
            Dictionary<int, Parking_Space> lps = new Dictionary<int, Parking_Space>();
            MySqlDataReader reader = null;
            string sql = "select * from parkingspace where garageID = '" + garageID + "' ";
            Connection conn = CreateConnAndGetValidConn(bq);
            if (conn == null)
            {
                Console.WriteLine("请检查网络！等待网络修复超时");
            }
            else
            {
                try
                {
                    DBAccess access = new DBAccess(sql, conn, CommandTypes.QUERYCOMMAND);
                    object result = access.GetResult();
                    reader = (MySqlDataReader)result;
                    while (reader.Read())
                    {
                        if (reader.HasRows)
                        {
                            Parking_Space ps = new Parking_Space();
                            ps.parkingSpaceID = reader.GetInt32("parkingSpaceID");
                            ps.parkingSpaceX = reader.GetInt32("parkingSpaceX");
                            ps.parkingSpaceY = reader.GetInt32("parkingSpaceY");
                            ps.parkingSpaceZ = reader.GetInt32("parkingSpaceZ");
                            ps.parkingSpaceState = reader.GetInt32("parkingSpaceState");
                            ps.garageID = garageID;
                            lps.Add(ps.parkingSpaceID, (Parking_Space)ps.Clone());
                        }
                    }
                    ConnectionPoolManager.ReleaseConnection(conn, bq);
                    return lps;
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.Message + "查询车位表异常");
                    if (conn != null)
                    {
                        conn.Dispose();
                    }
                    ConnectionPoolManager.AddConnToPooling(1, ConnectionPoolManager.remoteConf);
                }
                finally
                {
                    if (reader != null)
                    {
                        reader.Close();
                        reader.Dispose();
                    }
                }
            }
            return null;
        }
        /// <summary>
        /// 根据车牌查询得到车库id和车位id以及轮距
        /// </summary>
        /// <param name="bq"></param>
        /// <param name="numberPlate"></param>
        /// <returns></returns>
        public Vehicle GetVehicle(BlockingQueue bq, string numberPlate)
        {
            Vehicle v = new Vehicle();
            MySqlDataReader reader = null;
            string sql = "select * from vehicle where numberPlate = '" + numberPlate + "'";
            Connection conn = CreateConnAndGetValidConn(bq);
            if (conn == null)
            {
                Console.WriteLine("请检查网络！等待网络修复超时");
            }
            else
            {
                try
                {
                    DBAccess access = new DBAccess(sql, conn, CommandTypes.QUERYCOMMAND);
                    object result = access.GetResult();
                    reader = (MySqlDataReader)result;
                    while (reader.Read())
                    {
                        if (reader.HasRows)
                        {
                            int parkingSpaceID = reader.GetInt32("parkingSpaceID");
                            int garageID = reader.GetInt32("garageID");
                            int frontwheelbase = reader.GetInt32("frontwheelbase");
                            int rearwheelbase = reader.GetInt32("rearwheelbase");
                            v.parkingRecordsID = reader.GetInt32("parkingRecordsID");
                            v.parkingSpaceID = parkingSpaceID;
                            v.garageID = garageID;
                            v.frontwheelbase = frontwheelbase;
                            v.rearwheelbase = rearwheelbase;
                        }
                    }
                    ConnectionPoolManager.ReleaseConnection(conn, bq);
                    return v;
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.Message + "查询车辆表异常");
                    if (conn != null)
                    {
                        conn.Dispose();
                    }
                    ConnectionPoolManager.AddConnToPooling(1, ConnectionPoolManager.remoteConf);
                }
                finally
                {
                    if (reader != null)
                    {
                        reader.Close();
                        reader.Dispose();
                    }
                }
            }
            return null;
        }
        /// <summary>
        /// 根据车位id获得x,y,z
        /// </summary>
        /// <param name="bq"></param>
        /// <param name="parkingSpaceID"></param>
        /// <returns></returns>
        public Parking_Space GetFetchingSpace(BlockingQueue bq, int parkingSpaceID)
        {
            Parking_Space ps = new Parking_Space();
            MySqlDataReader reader = null;
            string sql = "select * from parkingspace where parkingSpaceID = '" + parkingSpaceID + " '";
            Connection conn = CreateConnAndGetValidConn(bq);
            if (conn == null)
            {
                Console.WriteLine("请检查网络！等待网络修复超时");
            }
            else
            {
                try
                {
                    DBAccess access = new DBAccess(sql, conn, CommandTypes.QUERYCOMMAND);
                    object result = access.GetResult();
                    reader = (MySqlDataReader)result;
                    while (reader.Read())
                    {
                        if (reader.HasRows)
                        {
                            ps.parkingSpaceID = parkingSpaceID;
                            ps.parkingSpaceX = reader.GetInt32("parkingSpaceX");
                            ps.parkingSpaceY = reader.GetInt32("parkingSpaceY");
                            ps.parkingSpaceZ = reader.GetInt32("parkingSpaceZ");
                        }
                    }
                    ConnectionPoolManager.ReleaseConnection(conn, bq);
                    return ps;
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.Message + "查询车位表获取x,y,z异常");
                    if (conn != null)
                    {
                        conn.Dispose();
                    }
                    ConnectionPoolManager.AddConnToPooling(1, ConnectionPoolManager.remoteConf);
                }
                finally
                {
                    if (reader != null)
                    {
                        reader.Close();
                        reader.Dispose();
                    }
                }
            }
            return null;
        }
        /// <summary>
        /// 查询手机号是否被注册
        /// </summary>
        /// <param name="bq"></param>
        /// <param name="tel"></param>
        /// <returns></returns>
        public bool IsTelRegister(BlockingQueue bq, string tel)
        {
            bool isTelRegister = false;
            string sql = "select * from user where userTelephone = '" + tel + "'";
            Connection conn = CreateConnAndGetValidConn(bq);
            if (conn == null)
            {
                Console.WriteLine("请检查网络！等待网络修复超时");
            }
            else
            {
                try
                {
                    DBAccess access = new DBAccess(sql, conn, CommandTypes.SCALARCOMMAND);
                    object result = access.GetResult();
                    int count = (int)result;
                    if (count > 0)
                    {
                        isTelRegister = true;
                    }
                    else
                    {
                        isTelRegister = false;
                    }
                    ConnectionPoolManager.ReleaseConnection(conn, bq);
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.Message + "检测电话号码注册异常");
                    if (conn != null)
                    {
                        conn.Dispose();
                    }
                    ConnectionPoolManager.AddConnToPooling(1, ConnectionPoolManager.remoteConf);
                }
            }
            return isTelRegister;
        }
        /// <summary>
        /// 查询停车记录id
        /// </summary>
        /// <param name="bq"></param>
        /// <param name="numberPlate"></param>
        /// <returns></returns>
        public int GetParkingRecordsID(BlockingQueue bq, string numberPlate)
        {
            int parkingRecordsID = 0;
            MySqlDataReader reader = null;
            string sql = "select parkingRecordsID from parkingrecords where numberPlate = '" + numberPlate + "' and parkingRecordsState = 3";
            Connection conn = CreateConnAndGetValidConn(bq);
            if (conn == null)
            {
                Console.WriteLine("请检查网络！等待网络修复超时");
            }
            else
            {
                try
                {
                    DBAccess access = new DBAccess(sql, conn, CommandTypes.QUERYCOMMAND);
                    object result = access.GetResult();
                    reader = (MySqlDataReader)result;
                    while (reader.Read())
                    {
                        if (reader.HasRows)
                        {
                            parkingRecordsID = reader.GetInt32("parkingRecordsID");
                        }
                        else
                        {
                            Console.WriteLine("停车记录id查无结果");
                        }
                    }
                    ConnectionPoolManager.ReleaseConnection(conn, bq);
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.Message + "查询停车记录id异常");
                    if (conn != null)
                    {
                        conn.Dispose();
                    }
                    ConnectionPoolManager.AddConnToPooling(1, ConnectionPoolManager.remoteConf);
                }
                finally
                {
                    if (reader != null)
                    {
                        reader.Close();
                        reader.Dispose();
                    }
                }
            }
            return parkingRecordsID;
        }

        /// <summary>
        /// 车库有无此车
        /// </summary>
        /// <param name="bq"></param>
        /// <param name="numberPlate"></param>
        /// <param name="garageID"></param>
        /// <returns></returns>
        public bool IsNumberPlate(BlockingQueue bq, string numberPlate, int garageID)
        {
            bool isNumberPlate = true;
            string sql = "select * from parkingrecords where numberPlate = '" + numberPlate + "' and parkingRecordsState = 3 and garageID = '" + garageID + "'";
            Connection conn = CreateConnAndGetValidConn(bq);
            if (conn == null)
            {
                Console.WriteLine("请检查网络！等待网络修复超时");
            }
            else
            {
                try
                {
                    DBAccess access = new DBAccess(sql, conn, CommandTypes.SCALARCOMMAND);
                    object result = access.GetResult();
                    int count = (int)result;
                    if (count > 0)
                    {
                        isNumberPlate = true;
                    }
                    else
                    {
                        isNumberPlate = false;
                    }
                    ConnectionPoolManager.ReleaseConnection(conn, bq);
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.Message + "检测车库中车辆异常");
                    if (conn != null)
                    {
                        conn.Dispose();
                    }
                    ConnectionPoolManager.AddConnToPooling(1, ConnectionPoolManager.remoteConf);
                }
            }
            return isNumberPlate;
        }
        /// <summary>
        /// 判断车辆表中是否存在该车辆号牌
        /// </summary>
        /// <param name="bq"></param>
        /// <param name="numberPlate"></param>
        /// <returns></returns>
        public bool IsNumberPlateFromVehicle(BlockingQueue bq, string numberPlate)
        {
            bool isNumberPlateFromVehicle = true;
            string sql = "select * from vehicle where numberPlate = '" + numberPlate + "' and vehiclepParkState = 1";
            Connection conn = CreateConnAndGetValidConn(bq);
            if (conn == null)
            {
                Console.WriteLine("请检查网络！等待网络修复超时");
            }
            else
            {
                try
                {
                    DBAccess access = new DBAccess(sql, conn, CommandTypes.SCALARCOMMAND);
                    object result = access.GetResult();
                    int count = (int)result;
                    if (count > 0)
                    {
                        isNumberPlateFromVehicle = true;
                    }
                    else
                    {
                        isNumberPlateFromVehicle = false;
                    }
                    ConnectionPoolManager.ReleaseConnection(conn, bq);
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.Message + "检测车辆表车辆号牌异常");
                    if (conn != null)
                    {
                        conn.Dispose();
                    }
                    ConnectionPoolManager.AddConnToPooling(1, ConnectionPoolManager.remoteConf);
                }
            }
            return isNumberPlateFromVehicle;
        }
        /// <summary>
        /// 根据车牌号更新车辆状态
        /// </summary>
        /// <param name="bq"></param>
        /// <param name="numberPlate"></param>
        /// <param name="vehiclepParkState"></param>
        public void UpdateVehicleParkState(BlockingQueue bq, string numberPlate, int vehiclepParkState)
        {
            string sql = "update vehicle set vehiclepParkState = '" + vehiclepParkState + "'where numberPlate = '" + numberPlate + "'";
            Connection conn = CreateConnAndGetValidConn(bq);
            if (conn == null)
            {
                Console.WriteLine("请检查网络！等待网络修复超时");
            }
            else
            {
                try
                {
                    DBAccess access = new DBAccess(sql, conn, CommandTypes.NOQUERYCOMMAND);
                    object result = access.GetResult();
                    ConnectionPoolManager.ReleaseConnection(conn, bq);
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.Message + "更新车辆状态失败");
                    if (conn != null)
                    {
                        conn.Dispose();
                    }
                    ConnectionPoolManager.AddConnToPooling(1, ConnectionPoolManager.remoteConf);
                }
            }
        }
        /// <summary>
        /// 更新车位状态
        /// </summary>
        /// <param name="bq"></param>
        /// <param name="parkingSpaceID"></param>
        /// <param name="parkingSpaceState"></param>
        public void UpdateParkingSpaceState(BlockingQueue bq, int parkingSpaceID, int parkingSpaceState)
        {
            string sql = "update parkingspace set parkingSpaceState = '" + parkingSpaceState + "'where parkingSpaceID = '" + parkingSpaceID + "'";
            Connection conn = CreateConnAndGetValidConn(bq);
            if (conn == null)
            {
                Console.WriteLine("请检查网络！等待网络修复超时");
            }
            else
            {
                try
                {
                    DBAccess access = new DBAccess(sql, conn, CommandTypes.NOQUERYCOMMAND);
                    object result = access.GetResult();
                    ConnectionPoolManager.ReleaseConnection(conn, bq);
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.Message + "更新车位状态失败");
                    if (conn != null)
                    {
                        conn.Dispose();
                    }
                    ConnectionPoolManager.AddConnToPooling(1, ConnectionPoolManager.remoteConf);
                }
            }
        }
        /// <summary>
        /// 插入停车记录表事务
        /// </summary>
        /// <param name="bq"></param>
        /// <param name="strs"></param>
        /// <returns></returns>
        public static int InsertParkingRecords(BlockingQueue bq, List<string> strs)
        {
            int parkingRecordsID = 0;
            Connection conn = CreateConnAndGetValidConn(bq);
            if (conn == null)
            {
                Console.WriteLine("请检查网络！等待网络修复超时");
            }
            else
            {
                try
                {
                    DBAccess access = new DBAccess(null, conn, CommandTypes.TRANSACTIONCOMMAND);
                    TransactionResult transactionResult = access.DealTransaction(strs);
                    parkingRecordsID = transactionResult.result;
                    ConnectionPoolManager.ReleaseConnection(conn, bq);
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.Message + "停车记录ID获取失败");
                    if (conn != null)
                    {
                        conn.Dispose();
                    }
                    ConnectionPoolManager.AddConnToPooling(1, ConnectionPoolManager.remoteConf);
                }
            }
            return parkingRecordsID;
        }
        /// <summary>
        /// 更新数据库事务
        /// </summary>
        /// <param name="bq"></param>
        /// <param name="strs"></param>
        public static bool UpdateTransaction(BlockingQueue bq, List<string> strs)
        {
            bool flag = true;
            Connection conn = ConnectionPoolManager.GetConnection(bq, TIMEOUT);
            int i = 0;
            while (conn == null && i < 2)
            {
                Console.WriteLine("为从连接池获取连接--------->UpdateTransaction" + i);
                ConnectionPoolManager.CheckConnPooling(2, 10, ConnectionPoolManager.remoteConf, bq);
                conn = ConnectionPoolManager.GetConnection(bq, TIMEOUT);
                i++;
            }
            if (conn == null)
            {
                Console.WriteLine("请检查网络！等待网络修复超时");
            }
            else
            {
                try
                {
                    DBAccess access = new DBAccess(null, conn, CommandTypes.TRANSACTIONCOMMAND);
                    TransactionResult transactionResult = access.DealTransaction(strs);
                    flag = transactionResult.flag;
                    ConnectionPoolManager.ReleaseConnection(conn, bq);
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.Message + "更新事务失败");
                    if (conn != null)
                    {
                        conn.Dispose();
                    }
                    ConnectionPoolManager.AddConnToPooling(1, ConnectionPoolManager.remoteConf);
                }
            }
            return flag;
        }

        /// <summary>
        /// 创建连接并获取有效连接
        /// </summary>
        /// <param name="bq"></param>
        /// <returns></returns>
        private static Connection CreateConnAndGetValidConn(BlockingQueue bq)
        {
            Connection conn = ConnectionPoolManager.GetConnection(bq, TIMEOUT);
            int i = 0;
            while (conn == null && i < 2)
            {
                Console.WriteLine("为从连接池获取连接--------->InsertParkingRecords" + i);
                ConnectionPoolManager.CheckConnPooling(2, 10, ConnectionPoolManager.remoteConf, bq);
                conn = ConnectionPoolManager.GetConnection(bq, TIMEOUT);
                i++;
            }
            return conn;
        }
        /// <summary>
        /// 清除超时连接
        /// </summary>
        /// <param name="ip"></param>
        /// <param name="TimeOut"></param>
        /// <param name="bq"></param>
        public static void KillTimeOutConnection(string ip, int TimeOut, BlockingQueue bq)
        {
            object result = null;
            string ipmohu = "'%" + ip + "%'";
            string sql = null;
            List<string> killidlist = new List<string>();
            if (ip == null)
            {
                sql = "select concat('KILL ',id,';') from information_schema.processlist where Time > " + @TimeOut;
            }
            else
            {
                sql = "select concat('KILL ',id,';') from information_schema.processlist where host like" + @ipmohu + " and Time >= " + @TimeOut;
            }
            DBAccess dba = new DBAccess();
            dba.sql = sql;
            dba.conn = CreateConnAndGetValidConn(bq);
            dba.commType = CommandTypes.QUERYCOMMAND;
            if (dba.conn != null)
            {
                try
                {
                    result = dba.GetResult();
                    if (result != null)
                    {
                        MySqlDataReader rdr = (MySqlDataReader)result;
                        while (rdr.Read())
                        {
                            killidlist.Add((string)rdr[0]);
                        }
                        rdr.Close();
                        foreach (string str in killidlist)
                        {
                            //Console.WriteLine(str);
                            dba.sql = str;
                            dba.commType = CommandTypes.NOQUERYCOMMAND;
                            dba.GetResult();
                        }                        
                    }
                    if (dba.conn != null)
                    {
                        dba.conn.Dispose();
                    }
                }
                catch (Exception)
                {
                    Console.WriteLine("连接为空，kill失败");
                }
            }
            else
            {
                Console.WriteLine("连接为空，kill失败");
            }
        }

    }
}
