using System;
using System.Data;
using System.Collections;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Collections.Generic;
using System.Text;


namespace digioz
{
    /// <summary>
    /// User Management Class
    /// </summary>
    public class UserManagement
    {
        private static PortalSettings coPortalSettings;

        public UserManagement()
        { }

        public static User GetUserByID(int piID)
        {
            User loUser = null;
            coPortalSettings = PortalSettingsManagement.GetPortalSettings();

            if (coPortalSettings.DBRelational == true)
            {
                string lsSQL = "SELECT * FROM tblUsers WHERE id=" + piID + ";";
                loUser = LoadUserInformation(lsSQL);
            }
            else
            {
                IDataNonRelational loDB = DataFactoryNonRelational.GetDataObject(coPortalSettings);
                loDB.openEntity();
                loUser = (User)loDB.GetEntity("User", piID);
                RijndaelEnhanced loRijndaelEnhanced = new RijndaelEnhanced(coPortalSettings.EncryptionKey, coPortalSettings.EncryptionVector);
                loUser.Password = loRijndaelEnhanced.Decrypt(loUser.PasswordEncrypted);
                loDB.closeEntity();
            }

            return loUser;
        }

        public static User GetUserByUsername(string psUsername)
        {
            User loUser = null;
            coPortalSettings = PortalSettingsManagement.GetPortalSettings();

            if (coPortalSettings.DBRelational == true)
            {
                string lsSQL = "SELECT * FROM tblUsers WHERE username='" + psUsername + "';";
                loUser = LoadUserInformation(lsSQL);
            }
            else
            {
                IDataNonRelational loDB = DataFactoryNonRelational.GetDataObject(coPortalSettings);
                loDB.openEntity();
                IEnumerable loObjs = loDB.GetEntity("User");
                foreach (object obj in loObjs)
                {
                    User loTempUser = (User)obj;
                    if (loTempUser.Username == psUsername)
                    {
                        loUser = loTempUser;
                        RijndaelEnhanced loRijndaelEnhanced = new RijndaelEnhanced(coPortalSettings.EncryptionKey, coPortalSettings.EncryptionVector);
                        loUser.Password = loRijndaelEnhanced.Decrypt(loUser.PasswordEncrypted);
                        break;
                    }                    
                }
                loDB.closeEntity();
            }

            return loUser;
        }

        public static bool SaveUserPassword(string psPassword, string psUserId)
        {
            coPortalSettings = PortalSettingsManagement.GetPortalSettings();
            bool lbResult = false;

            if (coPortalSettings.DBRelational == true)
            {
                IDataRelational loDB = DataFactory.GetDataObject(coPortalSettings);
                string lsSQL = String.Empty;
                string lsPasswordEncrypted = String.Empty;

                lsPasswordEncrypted = EncryptPassword(psPassword);
                lsSQL = "Update tblUsers SET password='" + lsPasswordEncrypted
                        + "' WHERE id=" + psUserId + ";";

                loDB.openConnection();
                loDB.ExecDB(lsSQL);
                loDB.closeConnection();
                lbResult = true;
            }
            else
            {
                digioz.XML xml = new XML(coPortalSettings);
                User loUser = (User)xml.GetEntity("User", int.Parse(psUserId));
                if (loUser != null)
                {
                    loUser.Password = psPassword;
                    xml.SaveEntity(loUser);
                }
            }

            return lbResult;
        }

        public static string EncryptPassword(string psPassword)
        {
            RijndaelEnhanced lsRijndael = new RijndaelEnhanced(coPortalSettings.EncryptionKey, coPortalSettings.EncryptionVector);
            return lsRijndael.Encrypt(psPassword);
        }

        public static string DecryptPassword(string psPassword)
        {
            coPortalSettings = PortalSettingsManagement.GetPortalSettings();

            RijndaelEnhanced lsRijndael = new RijndaelEnhanced(coPortalSettings.EncryptionKey, coPortalSettings.EncryptionVector);
            return lsRijndael.Decrypt(psPassword);
        }

        public static bool SaveUserPermission(string psPermission, string psUsername)
        {
            coPortalSettings = PortalSettingsManagement.GetPortalSettings();
            bool lbResult = false;

            if (coPortalSettings.DBRelational == true)
            {
                IDataRelational loDB = DataFactory.GetDataObject(coPortalSettings);
                string lsSQL = String.Empty;

                lsSQL = "UPDATE tblUsers SET permission='" + psPermission
                + "' WHERE username='" + psUsername + "';";

                try
                {
                    loDB.openConnection();
                    loDB.ExecDB(lsSQL);
                    lbResult = string.IsNullOrEmpty(loDB.sErr);
                }
                finally
                {
                    loDB.closeConnection();
                }
            }
            else
            {
                IDataNonRelational loDB = DataFactoryNonRelational.GetDataObject(coPortalSettings);
                IEnumerable loObjs = loDB.GetEntity("User");
                foreach (object obj in loObjs)
                {
                    User loUser = (User)obj;
                    if (loUser.Username == psUsername)
                    {
                        loUser.Permission = psPermission;
                        loDB.SaveEntity(loUser);
                        break;
                    }                    
                }
            }

            return lbResult;
        }

        public static bool IsUsernameAvailable(string psUsername)
        {
            Boolean lbIsAvailable = false;
            coPortalSettings = PortalSettingsManagement.GetPortalSettings();

            if (coPortalSettings.DBRelational == true)
            {
                IDataRelational loDB = DataFactory.GetDataObject(coPortalSettings);
                string lsSQL = "SELECT COUNT(*) FROM tblUsers WHERE username='" + psUsername + "';";

                string lsCount;

                try
                {
                    loDB.openConnection();
                    lsCount = (string)loDB.ExecDBScalar(lsSQL);
                    loDB.closeConnection();
                }
                catch
                {
                    lsCount = "0";
                }

                if (lsCount == "0")
                {
                    lbIsAvailable = true;
                }
                else
                {
                    lbIsAvailable = false;
                }
            }
            else
            {
                IDataNonRelational loDB = DataFactoryNonRelational.GetDataObject(coPortalSettings);
                IEnumerable loObjs = loDB.GetEntity("User");
                int liCount = 0;
                foreach (object obj in loObjs)
                {
                    User loUser = (User)obj;
                    if (loUser.Username == psUsername)
                    {
                        liCount++;
                        break;
                    }
                }
                lbIsAvailable = liCount > 0 ? false : true;
            }

            return lbIsAvailable;
        }

        public static UserPermissionList GetUserPermissions()
        {
            coPortalSettings = PortalSettingsManagement.GetPortalSettings();
            UserPermissionList loPermission = new UserPermissionList();

            if (coPortalSettings.DBRelational == true)
            {
                IDataRelational loDB = DataFactory.GetDataObject(coPortalSettings);
                string lsSQLPermissions = "SELECT * FROM tblUserPermission";

                try
                {
                    loDB.openConnection();
                    DataTable loUserPermissionTable = loDB.QueryDBDataset(lsSQLPermissions);
                    UserPermission loUserPermission;
                    foreach (DataRow loDR in loUserPermissionTable.Rows)
                    {
                        loUserPermission = 
                            new UserPermission(Convert.ToInt32(loDR["permission_id"]),
                                               Convert.ToString(loDR["permission_value"]),
                                               Convert.ToString(loDR["permission_description"]));
                        loPermission.Add(loUserPermission);
                    }
                }
                finally
                {
                    loDB.closeConnection();
                }
            }
            else
            {
                IDataNonRelational loDB = DataFactoryNonRelational.GetDataObject(coPortalSettings);
                IEnumerable loObjs = loDB.GetEntity("UserPermission");                
            }

            return loPermission;
        }
        private static User LoadUserInformation(string psSQL)
        {
            User loUser = new User();
            coPortalSettings = PortalSettingsManagement.GetPortalSettings();
            if (coPortalSettings.DBRelational == true)
            {
                IDataRelational loDB = DataFactory.GetDataObject(coPortalSettings);

                loDB.openConnection();
                DataTable loUserTable = loDB.QueryDBDataset(psSQL);
                loDB.closeConnection();

                if (loUserTable.Rows.Count != 0)
                {
                    loUser.ID = Convert.ToInt16(loUserTable.Rows[0][0].ToString());
                    loUser.Username = loUserTable.Rows[0][1].ToString();
                    loUser.PasswordEncrypted = loUserTable.Rows[0][2].ToString();
                    loUser.Permission = loUserTable.Rows[0][3].ToString();
                    RijndaelEnhanced loRijndaelEnhanced = new RijndaelEnhanced(coPortalSettings.EncryptionKey, coPortalSettings.EncryptionVector);
                    loUser.Password = loRijndaelEnhanced.Decrypt(loUser.PasswordEncrypted);
                }
            }
            else
            {
                // ToDo? Cannot user psSQL for non-relational data storage
            }

            return loUser;
        }

        public static List<User> GetUserList()
        {
            List<User> retList = new List<User>();
            coPortalSettings = PortalSettingsManagement.GetPortalSettings();

            if (coPortalSettings.DBRelational == true)
            {
                IDataRelational loDB = DataFactory.GetDataObject(coPortalSettings);

                loDB.openConnection();
                StringBuilder sql = new StringBuilder();
                sql.Append("SELECT U.id,U.username,U.permission,UP.profile_Email FROM tblUsers U ");
                sql.Append("LEFT OUTER JOIN tblUserProfile UP ON U.username = UP.profile_username");

                DataTable loDT = loDB.QueryDBDataset(sql.ToString());
                
                foreach (DataRow loDR in loDT.Rows)
                {
                    User u = new User();
                    u.ID = (int)loDR.ItemArray[0];
                    u.Username = (string)loDR.ItemArray[1];
                    u.Permission = (string)loDR.ItemArray[2];
                    u.Email = (string)(loDR.ItemArray[3]);
                    u.IsSuperUser = ((string)loDR.ItemArray[2]).Equals("1");
                    retList.Add(u);
                }
                loDB.closeConnection();
            }
            else
            {
                IDataNonRelational loDB = DataFactoryNonRelational.GetDataObject(coPortalSettings);
                IEnumerable loObjs = loDB.GetEntity("User");
                foreach (object obj in loObjs)
                {
                    retList.Add((User)obj);
                }
            }

            return retList;
        }
    }
}
