Imports System
Imports System.Data
Imports System.Configuration
Imports ASPNET.StarterKit.TimeTracker.DataAccessLayer

Namespace ASPNET.StarterKit.TimeTracker.BusinessLogicLayer

    '****************************************************************************
    '
    ' TTUser Class
    '
    ' The TTUser class represents a Time Tracker user, including their unique
    ' userID and UserName.  Custom role information retrieved from the database
    ' is also stored in the TTUser class.
    '
    '****************************************************************************

    Public Class TTUser
        Public Const UserRoleNone As String = "0"
        Public Const UserRoleAdministrator As String = "1"
        Public Const UserRoleProjectManager As String = "2"
        Public Const UserRoleConsultant As String = "3"
        Public Const UserRoleAdminPMgr As String = UserRoleAdministrator + "," + UserRoleProjectManager
        Public Const UserRolePMgrConsultant As String = UserRoleProjectManager + "," + UserRoleConsultant

        Private _displayName As String = String.Empty
        Private _firstName As String = String.Empty
        Private _lastName As String = String.Empty
        Private _password As String = String.Empty
        Private _role As String = UserRoleNone
        Private _roleName As String
        Private _userID As Integer
        Private _userName As String

        Public Sub New()
        End Sub 'New

        Public Sub New(ByVal UserName As String)
            _userName = UserName
        End Sub 'New

        Public Sub New(ByVal UserID As Integer, ByVal UserName As String, ByVal Name As String, ByVal Role As String)
            _userID = UserID
            _userName = UserName
            _displayName = Name
            _role = Role
        End Sub 'New

        Public Property DisplayName() As String
            Get
                Return _displayName
            End Get
            Set(ByVal Value As String)
                _displayName = Value
            End Set
        End Property

        Public Property FirstName() As String
            Get
                Return _firstName
            End Get
            Set(ByVal Value As String)
                _firstName = Value
            End Set
        End Property

        Public Property LastName() As String
            Get
                Return _lastName
            End Get
            Set(ByVal Value As String)
                _lastName = Value
            End Set
        End Property

        Public Property Name() As String
            Get
                Return _displayName
            End Get
            Set(ByVal Value As String)
                _displayName = Value
            End Set
        End Property

        Public Property Password() As String
            Get
                Return _password
            End Get
            Set(ByVal Value As String)
                _password = Value
            End Set
        End Property

        Public Property Role() As String
            Get
                Return _role
            End Get
            Set(ByVal Value As String)
                _role = Value
            End Set
        End Property

        Public Property RoleName() As String
            Get
                Return _roleName
            End Get
            Set(ByVal Value As String)
                _roleName = Value
            End Set
        End Property

        Public Property UserID() As Integer
            Get
                Return _userID
            End Get
            Set(ByVal Value As Integer)
                _userID = Value
            End Set
        End Property

        Public Property UserName() As String
            Get
                Return _userName
            End Get
            Set(ByVal Value As String)
                _userName = Value
            End Set
        End Property

        '*********************************************************************
        '
        ' GetAllUsers Static Method
        ' Retrieves a list of all users.
        '
        '*********************************************************************

        Public Shared Function GetAllUsers(ByVal userID As Integer) As UsersCollection
            Return GetUsers(userID, TTUser.UserRoleAdministrator)
        End Function 'GetAllUsers

        '*********************************************************************
        '
        ' GetUsers Static Method
        ' Retrieves a list of users based on the specified userID and role.
        ' The list returned is restricted by role.  For instance, users with
        ' the role of Administrator can see all users, while users with the
        ' role of Consultant can only see themselves.
        '
        '*********************************************************************

        Public Shared Function GetUsers(ByVal userID As Integer, ByVal role As String) As UsersCollection
            Dim firstName As String = String.Empty
            Dim lastName As String = String.Empty

            Dim ds As DataSet = SqlHelper.ExecuteDataset(ConfigurationSettings.AppSettings(Web.Global.CfgKeyConnString), "TT_ListUsers", userID, Convert.ToInt32(role))
            Dim users As New UsersCollection()

            ' Separate Data into a collection of Users.
            Dim r As DataRow
            For Each r In ds.Tables(0).Rows
                Dim usr As New TTUser()
                usr.UserName = r("UserName").ToString()
                usr.Role = r("RoleID").ToString()
                usr.RoleName = r("RoleName").ToString()
                usr.UserID = Convert.ToInt32(r("UserID"))
                usr.Name = GetDisplayName(usr.UserName, firstName, lastName)
                usr.FirstName = firstName
                usr.LastName = lastName
                users.Add(usr)
            Next r
            Return users
        End Function 'GetUsers

        '*********************************************************************
        '
        ' GetDisplayName static method
        ' Gets the user's first and last name from the specified TTUser account source, which is
        ' set in Web.confg.
        '
        '*********************************************************************

        Public Shared Function GetDisplayName(ByVal userName As String, ByRef firstName As String, ByRef lastName As String) As String
            Dim displayName As String = String.Empty
            Dim dbName As String = String.Empty

            ' The DirectoryHelper class will attempt to get the user's first 
            ' and last name from the specified account source.
            DirectoryHelper.FindUser(userName, firstName, lastName)

            ' If the first and last name could not be retrieved, return the TTUserName.
            If firstName.Length > 0  Or lastName.Length >  0 Then
                displayName = firstName + " " + lastName
            Else
                dbName = GetDisplayNameFromDB(userName)
                If Not dbName Is String.Empty Then
                    displayName = dbName
                Else
                    displayName = userName
                End If
            End If
            Return displayName
        End Function 'GetDisplayName

        Public Shared Function GetDisplayNameFromDB(ByVal userName As String) As String
            Dim displayName As String = String.Empty
            displayName = CStr(SqlHelper.ExecuteScalar(ConfigurationSettings.AppSettings(Web.Global.CfgKeyConnString), "TT_GetUserDisplayName", userName))
            Return displayName
        End Function

        '*********************************************************************
        '
        ' ListManagers Static Method
        ' Retrieves a list of users with the role of Project Manager.
        '
        '*********************************************************************

        Public Shared Function ListManagers() As UsersCollection
            Dim firstName As String = String.Empty
            Dim lastName As String = String.Empty

            Dim ds As DataSet = SqlHelper.ExecuteDataset(ConfigurationSettings.AppSettings(Web.Global.CfgKeyConnString), CommandType.StoredProcedure, "TT_ListManagers")
            Dim managersArray As New UsersCollection()

            ' Separate Data into a list of collections.
            Dim r As DataRow
            For Each r In ds.Tables(0).Rows
                Dim usr As New TTUser()
                usr.UserName = r("UserName").ToString()
                usr.Role = r("RoleID").ToString()
                usr.UserID = Convert.ToInt32(r("UserID"))
                usr.Name = GetDisplayName(usr.UserName, firstName, lastName)
                usr.FirstName = firstName
                usr.LastName = lastName
                managersArray.Add(usr)
            Next r
            Return managersArray
        End Function 'ListManagers

        '*********************************************************************
        '
        ' Remove static method
        ' Removes a user from database
        '
        '*********************************************************************

        Public Shared Sub Remove(ByVal userID As Integer)
            SqlHelper.ExecuteNonQuery(ConfigurationSettings.AppSettings(Web.Global.CfgKeyConnString), "TT_DeleteUser", userID)
        End Sub 'Remove

        '*********************************************************************
        '
        ' Load method
        ' Retrieve user information from the data access layer
        ' returns True if user information is loaded successfully, false otherwise.
        '
        '*********************************************************************

        Public Function Load() As Boolean
            ' Get the user's information from the database
            Dim ds As DataSet = SqlHelper.ExecuteDataset(ConfigurationSettings.AppSettings(Web.Global.CfgKeyConnString), "TT_GetUserByUserName", _userName)

            If ds.Tables(0).Rows.Count <  1 Then
                Return False
            End If
            Dim dr As DataRow = ds.Tables(0).Rows(0)
            _userID = Convert.ToInt32(dr("UserID"))
            _userName = dr("UserName").ToString()
            _role = dr("RoleID").ToString()
            _password = IIf(dr("Password") Is DBNull.Value, "", dr("Password"))
            _displayName = GetDisplayName(_userName, _firstName, _lastName)

            Return True
        End Function 'Load

        '*********************************************************************
        '
        ' Save method
        ' Add or update user information in the database depending on the TT_UserID.
        ' Returns True if saved successfully, false otherwise.
        '
        '*********************************************************************

        Public Overloads Function Save() As Boolean
            Dim isUserFound As Boolean = False
            Dim isUserActiveManager As Boolean = True
            Return Save(False, isUserFound, isUserActiveManager)
        End Function 'Save

        '*********************************************************************
        '
        ' Save method
        ' Add or update user information in the database depending on the TTUserID.
        ' Returns True if saved successfully, false otherwise.
        '
        '*********************************************************************

        Public Overloads Function Save(ByVal checkUsername As Boolean, ByRef isUserFound As Boolean, ByRef isUserActiveManager As Boolean) As Boolean
            ' Determines whether object needs update or to be inserted.
            If _userID = 0 Then
                Return Insert(checkUsername, isUserFound)
            Else
                If _userID >  0 Then
                    Return Update(isUserActiveManager)
                Else
                    _userID = 0
                    Return False
                End If
            End If
        End Function 'Save

        Private Function Insert(ByVal checkUsername As Boolean, ByRef isUserFound As Boolean) As Boolean
            Dim firstName As String = String.Empty
            Dim lastName As String = String.Empty
            isUserFound = False

            If ConfigurationSettings.AppSettings(Web.Global.CfgKeyUserAcctSource) <> "None" Then
                ' Check to see if the user is in the NT SAM or Active Directory before inserting them
                ' into the Time Tracker database.  If a first or last name is returned, the user exists and
                ' can be inserted into the Time Tracker database.
                If checkUsername Then
                    TTUser.GetDisplayName(_userName, firstName, lastName)
                    isUserFound = firstName <> String.Empty  Or lastName <>  String.Empty
                End If
            Else
                checkUsername = False
                isUserFound = True
            End If


            If checkUsername And isUserFound Or Not checkUsername Then
                _userID = Convert.ToInt32(SqlHelper.ExecuteScalar(ConfigurationSettings.AppSettings(Web.Global.CfgKeyConnString), "TT_AddUser", _userName, _password, _displayName, Convert.ToInt32(_role)))
                isUserFound = True
            End If
            Return _userID >  0
        End Function 'Insert

        Private Function Update(ByRef isUserActiveManger As Boolean) As Boolean
            ' if new user role is a consultant, check if user is a active manager of one or more project. if so, no update is applied 
            If _role = UserRoleConsultant Then
                If Convert.ToInt32(SqlHelper.ExecuteScalar(ConfigurationSettings.AppSettings(Web.Global.CfgKeyConnString), "TT_GetManagerProjectCount", _userID)) >  0 Then
                    isUserActiveManger = True
                    Return False
                Else
                    isUserActiveManger = False
                End If
            End If
            Return 0 <  Convert.ToInt32(SqlHelper.ExecuteScalar(ConfigurationSettings.AppSettings(Web.Global.CfgKeyConnString), "TT_UpdateUser", _userID, _userName, _password, _displayName, Convert.ToInt32(_role)))
        End Function 'Update

        '*********************************************************************
        '
        ' UsersDB.Login() Method 
        '
        ' The Login method validates a email/password pair against credentials
        ' stored in the users database.  If the email/password pair is valid,
        ' the method returns user's name.
        '
        ' Other relevant sources:
        '     + UserLogin Stored Procedure
        '
        '*********************************************************************

        Public Function Login(ByVal email As String, ByVal password As String) As String

            Dim userName As String
            userName = CStr(SqlHelper.ExecuteScalar(ConfigurationSettings.AppSettings(Web.Global.CfgKeyConnString), "TT_UserLogin", email, password))

            If Not userName Is Nothing Or userName Is "" Then
                Return userName
            Else
                Return String.Empty
            End If

        End Function

    End Class 'TTUser
End Namespace 'ASPNET.StarterKit.TimeTracker.BusinessLogicLayer