using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;

namespace Sdaleo.Systems
{
    /// <summary>
    /// This class will try to load the needed assembly(s) for the specified DB System.
    /// If the Assembly load fails, we know that this system won't work (isn't available)
    /// </summary>
    public static class SystemAvailable
    {
        /// <summary>
        /// Keep track of previous checks, no need to do it over and over again
        /// </summary>
        private static Dictionary<DBSystem, bool> _PrevCheckMap = new Dictionary<DBSystem, bool>();

        /// <summary>
        /// Try to load the assembly(s) for the specified DB System
        /// </summary>
        /// <param name="dbsystem">DB system to load assembly(s) for</param>
        /// <returns>true, if successfully loaded, false otherwise</returns>
        public static bool Check(DBSystem dbsystem)
        {
            try
            {
                // Performance Optimization
                if (_PrevCheckMap.ContainsKey(dbsystem))
                    return _PrevCheckMap[dbsystem];

                // ... Else we must check
                switch (dbsystem)
                {
                    case DBSystem.SQL_SERVER:
                        {
                            Assembly asm = Assembly.Load("System.Data");
                            _PrevCheckMap[dbsystem] = (asm != null);
                            return _PrevCheckMap[dbsystem];
                        }

                    case DBSystem.SQL_CE:
                        {
                            Assembly asm = Assembly.Load("System.Data.SqlServerCe");
                            _PrevCheckMap[dbsystem] = (asm != null);
                            return _PrevCheckMap[dbsystem];
                        }

                    case DBSystem.ADVANTAGE:
                        {
                            Assembly asm = Assembly.Load("Advantage.Data.Provider");
                            _PrevCheckMap[dbsystem] = (asm != null);
                            return _PrevCheckMap[dbsystem];
                        }

                    case DBSystem.CTREE:
                        {
                            Assembly asm = Assembly.Load("System.Data.SqlServerCe");
                            _PrevCheckMap[dbsystem] = (asm != null);
                            return _PrevCheckMap[dbsystem];
                        }

                    case DBSystem.MYSQL:
                        {
                            Assembly asm = Assembly.Load("System.Data.SqlServerCe");
                            _PrevCheckMap[dbsystem] = (asm != null);
                            return _PrevCheckMap[dbsystem];
                        }

                    case DBSystem.POSTGRES:
                        {
                            Assembly asm = Assembly.Load("Devart.Data");
                            if(asm != null)
                               asm = Assembly.Load("Devart.Data.PostgreSql");
                            _PrevCheckMap[dbsystem] = (asm != null);
                            return _PrevCheckMap[dbsystem];
                        }

                    default:
                        _PrevCheckMap[dbsystem] = false;
                        return false;
                }
            }
            catch (Exception) { /* ignore */ }
            _PrevCheckMap[dbsystem] = false;
            return false;
        }
    }
}
