using System;
using System.IO;
using System.Web.Hosting;
using System.Data;
using System.Data.Common;
using System.Xml;
using System.Configuration.Provider;
using System.Configuration;
using System.Collections;
using System.Collections.Generic;
using System.Collections.Specialized;
using Winson.Framework.LogProviders;
using Winson.Framework.Utility;

namespace Winson.Framework.DBProviders
{
    partial class XmlDBProvider : DataBaseProvider
    {
        #region 私有属性
        private DbConnection _conn;
        private DbProviderFactory _provider;
        private bool _useTransaction = true;
        private string _dbFolder;
        private XmlHelper xmlOP;
        #endregion

        /// <summary>
        /// 获取当前连接对象
        /// </summary>
        public override DbConnection Conn()
        {
            return null;
        }

        #region 公有方法

        public override void UseTransaction(bool isuse)
        {
            _useTransaction = isuse;
        }

        public override int ExecuteNonQuery(DBAction dbAction, string tableName, string strSql,
                                            ArrayList fieldName, ArrayList fieldValue,
                                            NameValueCollection conditionValue)
        {
            CreateConnection();
            if (!Directory.Exists(_dbFolder + tableName))
                Directory.CreateDirectory(_dbFolder + tableName);

            string fileName = _dbFolder + tableName + Path.DirectorySeparatorChar + ".xml";
            xmlOP.LoadXML(fileName, XmlHelper.LoadType.FromLocalFile);

            try
            {
                //如果tableName不为空，即进行参数创建生成XPATH语句
                if (!String.IsNullOrEmpty(tableName) && fieldName != null && fieldName.Count > 0)
                {
                    XmlNode root = xmlOP.RootNode;
                    string str = string.Empty;
                    //生成相应的XPATH语句
                    switch (dbAction)
                    {
                        case DBAction.Insert:
                            for (int i = 0; i < fieldName.Count; i++)
                            {
                                str += "<" + fieldName[i].ToString() + ">" + fieldValue[i].ToString() + "<" + fieldName[i].ToString() + "/>";
                            }
                            xmlOP.CreateNodeElement(root, "Records", str);
                            break;
                        case DBAction.Update:
                            XmlNodeList nl = xmlOP.GetChildNodesFromRoot("Records");
                            foreach (XmlNode node in nl)
                            {
                                if (xmlOP.GetChildElementValue(node, "Id").Equals("01"))
                                {
                                    xmlOP.ModifyNodeElementValue(xmlOP.GetChildElement(node.ChildNodes, "Name"), "ok");
                                }
                            }
                            foreach (object name in fieldName)
                            {

                            }
                            strSql = strSql.Substring(0, strSql.Length - 1);
                            break;
                        case DBAction.Delete:
                            break;
                    }

                    xmlOP.SaveToFile(fileName).ToString();

                    //添加参数
                    for (int i = 0; i < fieldName.Count; i++)
                    {
                        // CreateParams(ref cmd, fieldName[i].ToString(), fieldValue[i]);
                    }
                }
            }
            catch (Exception e)
            {
                LogManage.OutputErrLog(e, new Object[] { strSql, fieldName, fieldValue, conditionValue });
                return 0;
            }
            return 0;

        }

        public override bool ExecuteBatch(DBAction dbAction, string tableName, List<ArrayList> fieldNameList, List<ArrayList> fieldValueList)
        {
            throw new NotImplementedException();
        }

        public override object ExecuteScalar(string strSql, NameValueCollection paramValue)
        {
            throw new NotImplementedException();
        }

        public override DataSet ExecuteDataset(string strSql, string tableName, NameValueCollection paramValue)
        {
            throw new NotImplementedException();
        }

        public override DbDataReader ExecuteReader(DbConnection conn, string strSql, NameValueCollection paramValue)
        {
            throw new NotImplementedException();
        }

        public override bool ExecuteProcedure(string procName, NameValueCollection paramValue)
        {
            throw new InvalidOperationException("XmlProvider does not support this function");
        }

        public override object ExecuteProcScalar(string procName, NameValueCollection paramValue)
        {
            throw new InvalidOperationException("XmlProvider does not support this function");
        }

        public override DataSet ExecuteProcDataset(string procName, string tableName, NameValueCollection paramValue)
        {
            throw new InvalidOperationException("XmlProvider does not support this function");
        }

        public override string GetPrimeKey(string tableName)
        {
            throw new NotImplementedException();
        }

        public override string GeneratePagerSql(string tableName, int limit, int currpage, string criteria, string orderby, string order)
        {
            throw new NotImplementedException();
        }

        public override string GenerateGetOneEntitySql(string tableName, string primeKey)
        {
            throw new NotImplementedException();
        }

        #endregion

        #region 私有方法
        /// <summary>
        /// 创建数据库连接
        /// </summary>
        private void CreateConnection()
        {
            try
            {
                xmlOP = new XmlHelper();
                _dbFolder = HostingEnvironment.MapPath(ConfigurationManager.ConnectionStrings[connStringName].ConnectionString);

            }
            catch (Exception e)
            {
                LogManage.OutputErrLog(e, new Object[] { });
            }
        }

        private bool CheckCondition(XmlNode node, NameValueCollection conditionValue)
        {
            if (conditionValue != null && conditionValue.Count > 0)
            {
                string conWhere = string.Empty;
                string conSql = string.Empty;

                for (int i = 0; i < conditionValue.Count; i++)
                {
                    DbParameter pa = _provider.CreateParameter();
                    //如参数名为where，则为自定义查询条件;如为sql,则为自定义的sql语句
                    if (conditionValue.GetKey(i).ToLower() == "where")
                    {
                        conWhere = conditionValue.GetValues(i).GetValue(0).ToString();
                        break;
                    }
                    else if (conditionValue.GetKey(i).ToLower() == "sql")
                    {
                        conSql = conditionValue.GetValues(i).GetValue(0).ToString();
                        break;
                    }
                    else
                    {
                        if (xmlOP.GetChildElementValue(node, conditionValue.GetKey(i)).Equals(conditionValue.GetValues(i).GetValue(0)))
                            return true;

                    }
                }

                return true;
            }
            else
                return true;
        }
        /// <summary>
        /// 设置变量参数
        /// </summary>
        /// <param name="cmd">DbCommand</param>
        /// <param name="paraName">参数名</param>
        /// <param name="paraValue">参数值</param>
        private void CreateParams(ref DbCommand cmd, string paraName, object paraValue)
        {
            DbParameter pa = _provider.CreateParameter();
            pa.ParameterName = "@" + paraName;
            pa.Value = paraValue;
            pa.DbType = getDbType(paraValue.GetType().ToString().Split('.')[1]);
            cmd.Parameters.Add(pa);
        }
        /// <summary>
        /// 生成存储过程参数
        /// </summary>
        /// <param name="cmd">DbCommand</param>
        /// <param name="conditionValue">条件参数集合</param>
        private void CreateProcParams(ref DbCommand cmd, NameValueCollection conditionValue)
        {
            if (conditionValue != null && conditionValue.Count > 0)
            {
                for (int i = 0; i < conditionValue.Count; i++)
                {
                    DbParameter pa = _provider.CreateParameter();
                    pa.ParameterName = "@" + conditionValue.GetKey(i);
                    pa.Value = conditionValue.GetValues(i).GetValue(0);
                    cmd.Parameters.Add(pa);
                }
            }
        }

        /// <summary>
        ///私有: 获取数据类型(DbType)
        /// </summary>
        /// <param name="typename">数据类型名称</param>
        /// <returns>DbType</returns>
        private DbType getDbType(string typename)
        {
            //DbType t;
            #region switch datatype
            switch (typename.ToLower())
            {
                case "bigint":
                case "int64":
                    return DbType.Int64;
                case "int":
                case "int32":
                    return DbType.Int32;
                case "smallint":
                case "int16":
                    return DbType.Int16;
                case "binary":
                case "image":
                case "byte[]":
                case "varbinary":
                    return DbType.Binary;
                case "tinyint":
                    return DbType.Byte;
                case "bit":
                case "boolean":
                    return DbType.Boolean;
                case "varchar":
                case "text":
                case "nvarchar":
                case "ntext":
                case "nchar":
                case "char":
                case "string":
                    return DbType.String;
                case "datetime":
                case "smalldatetime":
                case "timestamp":
                    return DbType.DateTime;
                case "Float":
                    return DbType.Double;
                case "decimal":
                case "money":
                case "smallmoney":
                    return DbType.Decimal;
                default:
                    return DbType.Object;
            }
            #endregion

        }
        #endregion

    }
}
