﻿namespace Dike.Core.Authorization.Users
{
    using System;
    using System.ComponentModel.DataAnnotations;
    using System.ComponentModel.DataAnnotations.Schema;

    /// <summary>
    /// Entity used to store user login attempts.
    /// </summary>
    /// <seealso cref="Dike.Core.Domain.Entities.Entity{TPrimaryKey}" />
    /// <seealso cref="Dike.Core.Domain.Entities.Auditing.IHasCreationTime" />
    /// <seealso cref="Dike.Core.Domain.Entities.IMayHaveTenant" />
    [Table("UserLoginAttempts")]
    public class UserLoginAttempt
            : Domain.Entities.Entity<long>, Domain.Entities.Auditing.IHasCreationTime, Domain.Entities.IMayHaveTenant
    {
        #region Fields

        /// <summary>
        /// Maximum length of <see cref="BrowserInfo"/> property.
        /// </summary>
        public const int MaxBrowserInfoLength = 256;

        /// <summary>
        /// Maximum length of <see cref="ClientIpAddress"/> property.
        /// </summary>
        public const int MaxClientIpAddressLength = 64;

        /// <summary>
        /// Maximum length of <see cref="ClientName"/> property.
        /// </summary>
        public const int MaxClientNameLength = 128;

        /// <summary>
        /// Max length of the <see cref="TenancyName"/> property.
        /// </summary>
        public const int MaxTenancyNameLength = MultiTenancy.TenantBase.MaxTenancyNameLength;

        /// <summary>
        /// Max length of the <see cref="TenancyName"/> property.
        /// </summary>
        public const int MaxUserNameOrEmailAddressLength = 255;

        #endregion Fields

        #region Constructors

        /// <summary>
        /// Initializes a new instance of the <see cref="UserLoginAttempt"/> class.
        /// </summary>
        public UserLoginAttempt()
        {
            CreationTime = Core.Timing.Clock.Now;
        }

        #endregion Constructors

        #region Properties

        /// <summary>
        /// Gets or sets the browser information if the login attempt comes from a web request.
        /// </summary>
        /// <value>The browser information if the login attempt comes from a web request.</value>
        [MaxLength(MaxBrowserInfoLength)]
        public virtual string BrowserInfo
        {
            get;
            set;
        }

        /// <summary>
        /// Gets or sets the client IP address.
        /// </summary>
        /// <value>The client IP address.</value>
        [MaxLength(MaxClientIpAddressLength)]
        public virtual string ClientIpAddress
        {
            get;
            set;
        }

        /// <summary>
        /// Gets or sets the name (computer name) of the client.
        /// </summary>
        /// <value>The name (computer name) of the client.</value>
        [MaxLength(MaxClientNameLength)]
        public virtual string ClientName
        {
            get;
            set;
        }

        /// <summary>
        /// Gets or sets the entity creation time.
        /// </summary>
        /// <value>The entity creation time.</value>
        public virtual DateTime CreationTime
        {
            get;
            set;
        }

        /// <summary>
        /// Gets or sets the login attempt result.
        /// </summary>
        /// <value>The login attempt result.</value>
        public virtual LoginResultType Result
        {
            get;
            set;
        }

        /// <summary>
        /// Gets or sets the name of the tenancy.
        /// </summary>
        /// <value>The name of the tenancy.</value>
        [MaxLength(MaxTenancyNameLength)]
        public virtual string TenancyName
        {
            get;
            set;
        }

        /// <summary>
        /// Gets or sets the tenant identifier for a tenant-level login attempt.
        /// </summary>
        /// <value>The tenant identifier for a tenant-level login attempt.</value>
        public virtual int? TenantId
        {
            get;
            set;
        }

        /// <summary>
        /// Gets or sets the user identifier if the user was identified.
        /// </summary>
        /// <value>The user identifier if the user was identified.</value>
        public virtual long? UserId
        {
            get;
            set;
        }

        /// <summary>
        /// Gets or sets the user name or email address.
        /// </summary>
        /// <value>The user name or email address.</value>
        [MaxLength(MaxUserNameOrEmailAddressLength)]
        public virtual string UserNameOrEmailAddress
        {
            get;
            set;
        }

        #endregion Properties
    }
}