using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using NHibernate;
using System.Collections;
using System.Security.Cryptography;
using FluentNHibernate.Cfg;
using System.Reflection;

namespace MixTraffic
{
    public partial class DataHelper
    {
        public static bool OutputSQLString { get; set; }
        private string m_databaseAddress;
        private int m_databasePort;
        private static readonly string databaseName = "casun_map";
        private static readonly string databaseAccount = "casun";
        private static readonly string accountPassword = "casunagv";
        private ISessionFactory m_factory = null;
        private object obj = new object();
        private string _connectionString;


        public ISession session
        {
            get
            {
                if (m_factory == null)
                {
                    lock (obj)
                    {
                        try
                        {
                            if (m_factory == null) m_factory = createSessionFactory();
                        }
                        catch { throw; }
                    }
                }
                return m_factory.OpenSession();
            }
        }
        public void initialize(string dbAddress, int dbPort)
        {
            m_databaseAddress = dbAddress;
            m_databasePort = dbPort;
            try
            {
                if (m_factory != null) m_factory.Dispose();
                m_factory = createSessionFactory();
            }
            catch { throw; }
        }
        public void initialize(string path)
        {
            _connectionString = "Data Source =" + path;
            try
            {
                if (m_factory != null) m_factory.Dispose();
                m_factory = createSessionFactory();
            }
            catch { throw; }
        }
        public void initialize(string strDatabaseServer,
                                      int databasePort,
                                      string strDatabaseName,
                                      string strUserName,
                                      string strPassword)
        {
            //if (m_sessionFactory != null) return;

            try
            {
                string connectionString = string.Format("Server={0};Port={1};Database={2};Uid={3};Pwd={4};",
                    strDatabaseServer, databasePort, strDatabaseName, strUserName, strPassword);
                FluentConfiguration config = Fluently.Configure()
                        .Database(FluentNHibernate.Cfg.Db.MsSqlConfiguration.MsSql2008
                        .ConnectionString(connectionString));

                Assembly curAssembly = Assembly.GetExecutingAssembly();
                NHibernate.Cfg.Configuration cfg = config.Mappings(m => m.FluentMappings.AddFromAssembly(curAssembly)).BuildConfiguration();
                m_factory = cfg.BuildSessionFactory();

                //  m_mappingSet.buildMappings(cfg);
            }
            catch { throw; }
        }
        public void close()
        {
            if (m_factory != null) { m_factory.Close(); m_factory = null; }
        }
        private ISessionFactory createSessionFactory()
        {
            try
            {

                //NHibernate.Cfg.Configuration
                string connectionString =_connectionString;// string.Format("Server={0};Port={1};Database={2};Uid={3};Pwd={4};",
                    //m_databaseAddress, m_databasePort, databaseName, databaseAccount, accountPassword);
                FluentConfiguration config = Fluently.Configure()
                        .Database(FluentNHibernate.Cfg.Db.MsSqlConfiguration.MsSql2008
                        .ConnectionString(connectionString));
                Assembly curAssembly = Assembly.GetExecutingAssembly();
                NHibernate.Cfg.Configuration cfg = config.Mappings(m => m.FluentMappings.AddFromAssembly(curAssembly))
                                                         .ExposeConfiguration(f => f.SetInterceptor(new SqlStatementInterceptor()))
                                                         .BuildConfiguration();
                return cfg.BuildSessionFactory();
            }
            catch { throw; }
        }



        public static string md5Encrypt(string strSource)
        {
            byte[] buffer = Encoding.UTF8.GetBytes(strSource);
            MD5 md5 = new MD5CryptoServiceProvider();
            byte[] output = md5.ComputeHash(buffer);
            return Convert.ToBase64String(output);
        }

        /*
        public static string GetLockerAddress(int locationID, ISession session)
        {
            try
            {
                IDbCommand cmd = session.Connection.CreateCommand();
                cmd.CommandText = "GetLockerAddress";
                cmd.CommandType = CommandType.StoredProcedure;
                IDbDataParameter p1 = cmd.CreateParameter();
                p1.ParameterName = "locationID";
                p1.Direction = ParameterDirection.Input;
                p1.Value = locationID;
                cmd.Parameters.Add(p1);
                IDbDataParameter p2 = cmd.CreateParameter();
                p2.ParameterName = "address";
                p2.Direction = ParameterDirection.Output;
                cmd.Parameters.Add(p2);
                cmd.ExecuteNonQuery();
                return p2.Value.ToString();
            }
            catch { throw; }
        }
        */

        public class SqlStatementInterceptor : EmptyInterceptor
        {
            public override NHibernate.SqlCommand.SqlString OnPrepareStatement(NHibernate.SqlCommand.SqlString sql)
            {
                //#if DEBUG
                try
                {
                    //File.AppendAllText("c:\\log.txt", string.Format("{0}\n", sql.ToString()));
                }
                catch
                {

                }
                //#endif
                return sql;
            }
        }

        /// <summary>
        /// 执行存储过程
        /// </summary>
        /// <param name="session"></param>
        /// <param name="procedureName"></param>
        /// <param name="inParams"></param>
        /// <param name="outParams"></param>
        public static void executeStoreProcedure(ISession session, string procedureName, Hashtable inParams, Hashtable outParams)
        {
            try
            {
                IDbCommand cmd = session.Connection.CreateCommand();
                cmd.CommandText = procedureName;
                cmd.CommandType = CommandType.StoredProcedure;

                //填充传入参数
                if (inParams != null)
                {
                    foreach (string key in inParams.Keys)
                    {
                        IDbDataParameter p = cmd.CreateParameter();
                        p.Direction = ParameterDirection.Input;
                        p.ParameterName = key;
                        p.Value = inParams[key];
                        cmd.Parameters.Add(p);
                    }
                }

                //填充传出参数
                if (outParams != null)
                {
                    foreach (string key in outParams.Keys)
                    {
                        IDbDataParameter p = cmd.CreateParameter();
                        p.Direction = ParameterDirection.Output;
                        p.ParameterName = key;
                        p.Value = inParams[key];
                        cmd.Parameters.Add(p);
                    }
                }

                cmd.ExecuteNonQuery();
            }
            catch { throw; }
        }



    }
}
