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

namespace Sdaleo.Systems
{
    /// <summary>
    /// Validation Consts used throughout Validation of Parameters
    /// </summary>
    public static class ValidationConsts
    {
        #region Validation Consts

        // Common
        public const string CharSet_CharsNum = "0123456789";
        public const string CharSet_CharsAlpha = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
        public const string CharSet_CharsAlphaNum = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
        public const string CharSet_CharsSambaComputerNames = CharSet_CharsAlphaNum + " -_";
        public const string CharSet_CharsIPAddress = CharSet_CharsNum + ".";
        public const string CharSet_CharsSpecialKeyboardAscii = " -_!@#$%^&*()_{}\\|:\":/?.,<>~`*-+[]'";

        // Not Allowed
        public const string CharSet_NotAllowedInFileNames = @"\/:*?<>|" + "\"";
        public const string CharSet_NotAllowedInDirectorPaths = @"/*?<>|" + "\"";
        
        // Allowed
        public const string CharSet_AllowedUserNames = CharSet_CharsAlphaNum + " -_";
        public const string CharSet_AllowedPasswords = CharSet_CharsAlphaNum + CharSet_CharsSpecialKeyboardAscii;
        public const string CharSet_AllowedServerNames = CharSet_CharsSambaComputerNames + CharSet_CharsIPAddress; // we allow IP addresses as computer names
        public const string CharSet_AllowedInstanceNames = CharSet_CharsAlphaNum + "$-_";
        public const string CharSet_AllowedDatabaseNames = CharSet_CharsAlphaNum + CharSet_CharsSpecialKeyboardAscii;
        public const string CharSet_AllowedTableNames = CharSet_CharsAlphaNum + " -_";                                       

        /// <summary>
        /// Generic Function to use with Allowed Character Sets above 
        /// </summary>
        /// <param name="TextToEvaluate">string to evaluate</param>
        /// <param name="TextToEvaluateWith">Pass in one of the legal character consts sets declared above</param>
        /// <returns>true if valid, false otherwise</returns>
        public static bool ContainsOnlyLegalChars(string TextToEvaluate, string TextToEvaluateWith)
        {
            foreach (char c in TextToEvaluate.ToCharArray())
            {
                bool bFound = (TextToEvaluateWith.IndexOf(c) >= 0);
                if (!bFound)
                    return false;
            }
            return true;
        }

        #endregion

        #region CredentialValidation

        /// <summary>
        /// Use this to validate a credential object against a specific system
        /// </summary>
        /// <param name="credential">credential object to validate</param>
        /// <param name="system">the system to validate against</param>
        /// <returns>DBerror that either contains or doesn't contain an error</returns>
        public static DBError IsCredentialValid(IConnectDb credential, DBSystem system)
        {
            if (credential == null)
                return DBError.Create("Invalid Credential Object Passed In");
            else if (credential.DBType != system)
                return DBError.Create("Credential Object doesn't match system");
            else if (!credential.IsValid)
                return DBError.Create("Credential is invalid");
            else
                return new DBError();
        }

        #endregion

        /// <summary>
        /// Common Generally Generic Validation Functions that should be the same across the board
        /// for all DBMS systems
        /// </summary>
        public static class Generic
        {
            /// <summary>
            /// Main Validation Function to validate Usernames
            /// </summary>
            /// <param name="strUserName">Username to validate</param>
            /// <returns>true if valid, false otherise</returns>
            public static bool IsValidUserName(string strUserName)
            {
                if (String.IsNullOrEmpty(strUserName))
                {
                    return false;
                }
                else if (strUserName.Length < 1 || strUserName.Length > 128) // limit User Name length
                {
                    return false;
                }
                else if (!ContainsOnlyLegalChars(strUserName, CharSet_AllowedUserNames))
                {
                    return false;
                }
                else
                {
                    return true;
                }
            }

            /// <summary>
            /// Main Validation Function to validate Passwords
            /// </summary>
            /// <param name="strPassword">Password to validate</param>
            /// <returns>true if valid, false otherise</returns>
            public static bool IsValidPassword(string strPassword)
            {
                if (String.IsNullOrEmpty(strPassword))
                {
                    return false;
                }
                else if (strPassword.Length < 1 || strPassword.Length > 128) // limit Password Length
                {
                    return false;
                }
                else if (!ContainsOnlyLegalChars(strPassword, CharSet_AllowedPasswords))
                {
                    return false;
                }
                else
                {
                    return true;
                }
            }

            /// <summary>
            /// Calls IsValidUser && IsValidPassword
            /// </summary>
            /// <returns>true if valid, false otherise</returns>
            internal static bool IsValidUserCredential(string strUserName, string strPassword)
            {
                return IsValidUserName(strUserName) && IsValidPassword(strPassword);
            }

            /// <summary>
            /// Main Validation Function to validate Server Names
            /// </summary>
            /// <param name="strServerName">Name of a Server</param>
            /// <returns>true if valid, false otherise</returns>
            internal static bool IsValidServerName(string strServerName)
            {
                if (String.IsNullOrEmpty(strServerName))
                {
                    return false;
                }
                // The maximum length for NetBIOS names is 15 characters. The maximum length for DNS computer names 
                // in an Active Directory environment is 24 characters
                else if (strServerName.Length < 1 || strServerName.Length > 24) // limit server Name length
                {
                    return false;
                }
                else if (!ContainsOnlyLegalChars(strServerName, CharSet_AllowedServerNames))
                {
                    return false;
                }
                else
                {
                    return true;
                }
            }

            /// <summary>
            /// Main Validation Function to validate Instancse Names
            /// </summary>
            /// <param name="strInstanceName">Name of an Instance</param>
            /// <returns>true if valid, false otherise</returns>
            internal static bool IsValidInstanceName(string strInstanceName)
            {
                if (string.IsNullOrEmpty(strInstanceName))
                {
                    return false;
                }
                else if (strInstanceName.Length < 1 || strInstanceName.Length > 16) // limit Instance Name length
                {
                    return false;
                }
                else if (!ContainsOnlyLegalChars(strInstanceName, CharSet_AllowedInstanceNames))
                {
                    return false;
                }
                else
                {
                    return true;
                }
            }

        }

        #region FileName and Path Validation

        /// <summary>
        /// Check to see if the filename is valid
        /// </summary>
        /// <param name="Filename">filename to check</param>
        /// <returns>true if valid, false otherwise</returns>
        public static bool IsValidFileName(string Filename)
        {
            if (!String.IsNullOrEmpty(Filename))
            {
                bool bIsValid = !ContainsOnlyLegalChars(Filename, CharSet_NotAllowedInFileNames);
                return bIsValid;
            }
            return false;
        }

        /// <summary>
        /// Check to see if directory path is valid
        /// </summary>
        /// <param name="Path">directory path</param>
        /// <returns>true if valid, false otherwise</returns>
        public static bool IsValidDirectoryPath(string Path)
        {
            if (!String.IsNullOrEmpty(Path))
            {
                bool bIsValid = !ContainsOnlyLegalChars(Path, CharSet_NotAllowedInDirectorPaths);
                return bIsValid;
            }
            return false;
        }

        /// <summary>
        /// Check to see if directory and file name are valid
        /// </summary>
        /// <param name="FileNameNPath">filename including path information</param>
        /// <returns>true if valid, false otherwise</returns>
        public static bool IsValidFileNameNPath(string FileNameNPath)
        {
            if(!String.IsNullOrEmpty(FileNameNPath))
            {
                string path = Path.GetDirectoryName(FileNameNPath);
                string file = Path.GetFileName(FileNameNPath);
                bool bValid = IsValidDirectoryPath(path) && IsValidFileName(file);
                return bValid;
            }
            return false;
        }

        #endregion
    }
}
