using System;
using System.Linq;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;

namespace INT99DC_7C.Part11_UserManager
{
    public partial class UserManager
    {
        #region Field
        // fnUserMgrDebugCB
        public const int USERMGR_DBG_NORMAL = 0x0001;
        public const int USERMGR_DBG_THREAD = 0x0002;
        public const int USERMGR_DBG_LIST = 0x0004;

        // fnUserMgrLoginCB
        public const int USERMGR_LOGIN_STATUS_OK = 0x00;
        public const int USERMGR_LOGIN_STATUS_ID_FAIL = 0x01;
        public const int USERMGR_LOGIN_STATUS_PW_FAIL = 0x02;

        // fnUserMgrLogoutCB
        public const int USERMGR_LOGOUT_STATUS_OK = 0x00;
        public const int USERMGR_LOGOUT_STATUS_FAIL = 0x01;

        // fnUserMgrDelUserCB
        //public const int USERMGR_DEL_STATUS_OK = 0x00;
        //public const int USERMGR_DEL_STATUS_NOK = 0x01;

        // lock_status
        public const int USERMGR_LOCK_STATUS_NONE = 0x00;
        public const int USERMGR_LOCK_STATUS_EXPIRE = 0x01;

        public const int USERMGR_ID_MIN_LENGTH = 6;
        public const int UERRMGR_ID_MAX_LENGTH = 20;

        public const int USERMGR_PW_MIN_LENGTH = 6;
        public const int USERMGR_PW_MAX_LENGTH = 20;

        public const int MAX_USER_ID_LENGTH = 32;
        public const int MAX_USER_PW_LEGNTH = 32;
        public const int MAX_USER_HISTORY_PW_COUNT = 3;

        public const int INVALID_VALUE = -1;
        public const int USERMGR_USER_ADMINISTRATOR = 1;
        public const int USERMGR_USER_NORMAL = 0;

        public const int EXPIRE_PERIOD_PASSWORD_NOT_SUPPORT = 0;
        public const int MAX_EXPIRE_PERIOD_PASSWORD = 90;
        public const int DEFAULT_PASSWORD_EXPIRE_PERIOD = 90;		// Days		password change	

        public const int EXPIRE_PERIOD_ACCOUNT_NOT_SUPPORT = 0;
        public const int MAX_EXPIRE_PERIOD_ACCOUNT = 180;
        public const int DEFAULT_ACCOUNT_LOCK_PERIOD = 180;		// Days		login 

        public const int MAX_LOGIN_AUTO_TIMEOUT = 90;
        public const int DEFAULT_LOGIN_WARNING_TIMEOUT_SEC = 60;		// 60 sec	during login, auto logout warning time
        public const int DEFAULT_LOGIN_AUTO_TIMEOUT_MIN = 30;		// 30 min	during login, auto logout timeout  

        public const int USER_MENU_ID_MAX = 30;                     // MenuID_t buffer Size

        public const int MAX_ACTIVE_LEVEL = 10;                     // menu active level
        public const int INVALID_ACTIVE_LEVEL = 0;
        #endregion

        #region Enum E_user_mgr_status
        public enum E_user_mgr_status
        {
            USER_MGR_STATUS_OK = 0x00,

            // error status
            USER_MGR_STATUS_ID_NOT_FOUND,			// 1 - not found the user id 
            USER_MGR_STATUS_ID_DUPLICATE,			// 2 - duplicate on id
            USER_MGR_STATUS_ID_LENGTH_UNDER,		// 3 - under the minimum length of id
            USER_MGR_STATUS_ID_LENGTH_OVER,			// 4 - over  the maximum length of id 
            USER_MGR_STATUS_ID_CONT_LETTER,			// 5 - continue characters or duplicate characters of id
            USER_MGR_STATUS_ID_INVALID_CHAR,		// 6 - include the invalid character on id
            USER_MGR_STATUS_ID_ACCOUNT_LOCK,        // 7 - Account Lock

            USER_MGR_STATUS_PW_DUPLICATE_HISTORY,	// 8 - duplicate on password history
            USER_MGR_STATUS_PW_LENGTH_UNDER,		// 9 - under the minimum length of password
            USER_MGR_STATUS_PW_LENGTH_OVER,			// 10 - over  the maximum length of password 
            USER_MGR_STATUS_PW_CONT_LETTER,			// 11 - continue characters or duplicate characters of password
            USER_MGR_STATUS_PW_INVALID_CHAR,		// 12 - include the invalid character on password
            USER_MGR_STATUS_PW_EACH_MIN_CHAR,		// 13 - not include minimum characters on password
            USER_MGR_STATUS_PW_NOT_SAME,			// 14 - password error
            USER_MGR_STATUS_PW_PASSWORD_LOCK,       // 15 - Password Lock

            USER_MGR_STATUS_OTHER_OVER_PASSWORD_PERIOD,	// 16 - over maximum password expire period (days)
            USER_MGR_STATUS_OTHER_OVER_ACCOUNT_PERIOD,	// 17 - over maximum account expire period (days)
            USER_MGR_STATUS_OTHER_OVER_LOGIN_TIMEOUT,	// 18 - over maximum auto logout time (minute)

            USER_MGR_STATUS_MAX,
        };
        #endregion

        #region Enum E_user_mgr_menu_id
        public enum E_user_mgr_menu_id
        {
            USER_MENU_ID_RESERVE_0 = 0x00,
            USER_MENU_ID_RESERVE_1,
            USER_MENU_ID_RESERVE_2,
            USER_MENU_ID_RESERVE_3,
            USER_MENU_ID_RESERVE_4,

            USER_MENU_ID_RESERVE_5,
            USER_MENU_ID_RESERVE_6,
            USER_MENU_ID_RESERVE_7,
            USER_MENU_ID_RESERVE_8,
            USER_MENU_ID_RESERVE_9,

            USER_MENU_ID_RESERVE_10,
            USER_MENU_ID_RESERVE_11,
            USER_MENU_ID_RESERVE_12,
            USER_MENU_ID_RESERVE_13,
            USER_MENU_ID_RESERVE_14,

            USER_MENU_ID_RESERVE_15,
            USER_MENU_ID_RESERVE_16,
            USER_MENU_ID_RESERVE_17,
            USER_MENU_ID_RESERVE_18,
            USER_MENU_ID_RESERVE_19,

            USER_MENU_ID_RESERVE_20,
            USER_MENU_ID_RESERVE_21,
            USER_MENU_ID_RESERVE_22,
            USER_MENU_ID_RESERVE_23,
            USER_MENU_ID_RESERVE_24,

            USER_MENU_ID_RESERVE_25,
            USER_MENU_ID_RESERVE_26,
            USER_MENU_ID_RESERVE_27,
            USER_MENU_ID_RESERVE_28,
            USER_MENU_ID_RESERVE_29,
            USER_MENU_ID_MAX,
        };
        #endregion

        #region Struct MenuID_t
        [StructLayout(LayoutKind.Sequential)]
        public struct MenuID_t
        {
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = (int)E_user_mgr_menu_id.USER_MENU_ID_MAX)]
            public bool[] fMenu;
        }
        #endregion

        #region Struct DateTime_t
        [StructLayout(LayoutKind.Sequential)]
        public struct DateTime_t
        {
            [MarshalAs(UnmanagedType.U2)]
            public UInt16 year;
            [MarshalAs(UnmanagedType.U1)]
            public byte month;
            [MarshalAs(UnmanagedType.U1)]
            public byte day;

            [MarshalAs(UnmanagedType.U1)]
            public byte hour;
            [MarshalAs(UnmanagedType.U1)]
            public byte minute;
            [MarshalAs(UnmanagedType.U1)]
            public byte second;
            [MarshalAs(UnmanagedType.U1)]
            public byte reserved;

            public static int Size
            {
                get { return (int)(sizeof(UInt16) + 6); }
            }

            public void SetDate(UInt16 year, byte month, byte day)
            {
                this.year = year;
                this.month = month;
                this.day = day;
            }

            public void SetTime(byte hour, byte minute, byte second)
            {
                this.hour = hour;
                this.minute = minute;
                this.second = second;
            }

            public string GetDateTime()
            {
                string dateTime;

                dateTime = string.Format("{0:D4}{1:D2}{2:D2}{3:D2}{4:D2}{5:D2}", year, month, day, hour, minute, second);

                return dateTime;
            }
        }
        #endregion

        #region Struct UserMgr_user_info_t
        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
        public struct UserMgr_user_info_t
        {
            [MarshalAs(UnmanagedType.I4)]
            public Int32 status;					// user_new_add_status_e

            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = MAX_USER_ID_LENGTH)]
            public string user_id;

            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = MAX_USER_PW_LEGNTH)]
            public string user_pw;

            [MarshalAs(UnmanagedType.I4)]
            public Int32 fadmin;

            [MarshalAs(UnmanagedType.I4)]
            public Int32 password_expire_period;        // password lock date

            [MarshalAs(UnmanagedType.I4)]
            public Int32 id_expire_period;  			// id lock date

            [MarshalAs(UnmanagedType.I4)]
            public Int32 id_flock_status;			    // user ID (account) lock status	

            [MarshalAs(UnmanagedType.I4)]
            public Int32 password_flock_status;			// password lock status			(need to change password)

            [MarshalAs(UnmanagedType.Struct)]
            public DateTime_t password_register_date;			// date/time when the user password was registered or changed

            [MarshalAs(UnmanagedType.Struct)]
            public DateTime_t id_login_date;				// date/time when the user was login   

            [MarshalAs(UnmanagedType.Struct)]
            public DateTime_t password_expire_date;     // Password Expiration Date

            [MarshalAs(UnmanagedType.Struct)]
            public DateTime_t id_expire_date;      // Account Expiration Date

            [MarshalAs(UnmanagedType.Struct)]
            public MenuID_t menuID;                     // flag of Menu IDs

            [MarshalAs(UnmanagedType.I4)]
            public Int32 active_level;                  // menu active level : max : MAX_ACTIVE_LEVEL

            [MarshalAs(UnmanagedType.I4)]
            public Int32 fFirstPW;                      // [1] First (request to modify), [0] Next (not request)
        }
        #endregion

        #region Struct UserMgr_user_modify_t
        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
        public struct UserMgr_user_modify_t
        {
            public int status;

            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = MAX_USER_ID_LENGTH)]
            public string user_id;
        }
        #endregion

        #region Struct UserMgr_user_del_t
        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
        public struct UserMgr_user_del_t
        {
            public int status;

            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = MAX_USER_ID_LENGTH)]
            public string user_id;
        }
        #endregion

        #region Struct UserMgr_login_timeout_t
        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
        public struct UserMgr_login_timeout_t
        {
            public int remainder_time;

            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = MAX_USER_ID_LENGTH)]
            public string user_id;
        }
        #endregion

        #region Struct UserMgr_user_add_t
        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
        public struct UserMgr_user_add_t
        {
            public int status;
            public int flock_status_account;
            public int flock_status_password;

            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = MAX_USER_ID_LENGTH)]
            public string user_id;
        }
        #endregion

        #region Struct UserMgr_user_lock_t
        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
        public struct UserMgr_user_lock_t
        {
            public int flock_status_account;
            public int flock_status_password;

            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = MAX_USER_ID_LENGTH)]
            public string user_id;
        }
        #endregion

        #region Struct UserMgr_user_list_t
        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
        public struct UserMgr_user_list_t
        {
            [MarshalAs(UnmanagedType.I4)]
            public int status;					// user_new_add_status_e

            [MarshalAs(UnmanagedType.I4)]
            public int total_count;

            [MarshalAs(UnmanagedType.I4)]
            public int index;

            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = MAX_USER_ID_LENGTH)]
            public string user_id;

            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = MAX_USER_PW_LEGNTH)]
            public string user_pw;

            [MarshalAs(UnmanagedType.I4)]
            public Int32 fadmin;

            [MarshalAs(UnmanagedType.I4)]
            public Int32 password_expire_period;                // password lock

            [MarshalAs(UnmanagedType.I4)]
            public Int32 id_expire_period;			// account lock

            [MarshalAs(UnmanagedType.I4)]
            public Int32 id_flock_status;			// user ID (account) lock	

            [MarshalAs(UnmanagedType.I4)]
            public Int32 flock_status_password;			// password lock			(need to change password)

            [MarshalAs(UnmanagedType.Struct)]
            public DateTime_t password_register_date;			// date/time when the user password was registered or changed

            [MarshalAs(UnmanagedType.Struct)]
            public DateTime_t id_login_date;				// date/time when the user was login  

            [MarshalAs(UnmanagedType.Struct)]
            public DateTime_t password_expire_date;     // Password Expiration Date

            [MarshalAs(UnmanagedType.Struct)]
            public DateTime_t id_expire_date;      // Account Expiration Date 

            [MarshalAs(UnmanagedType.I4)]
            public Int32 active_level;                  // menu active level : max : MAX_ACTIVE_LEVEL

            [MarshalAs(UnmanagedType.Struct)]
            public MenuID_t menuID;                     // flag of Menu IDs

            [MarshalAs(UnmanagedType.I4)]
            public Int32 fFirstPW;                      // flag first password 
        }
        #endregion

        #region Struct UserMgr_user_list_name_t
        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
        public struct UserMgr_user_list_name_t
        {
            public int total_count;
            public int index;

            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = MAX_USER_ID_LENGTH)]
            public string user_id;
        }
        #endregion
    }
}
