using System;
using System.Runtime.Serialization;
using System.Threading;
using MECF.Framework.Common.Account.Extends;

namespace Aitex.Core.Account;

/// <summary>
/// 登录凭据。
/// </summary>
/// <remarks>
/// RT使用该对象维护用户登录信息，包括：登录激活状态维持、WCF远程调用权限验证。
/// </remarks>
[Serializable]
[DataContract]
public class Credential
{
    #region Consturctors

    /// <summary>
    /// 创建登录凭据的实例。
    /// </summary>
    /// <remarks>
    /// 该构造函数用于WCF通讯，RT中创建该对象是请使用有参数的构造函数。
    /// </remarks>
    public Credential()
    {
        Token = Guid.Empty;
        State = CredentialState.Requesting;
        LoginTime = DateTime.MinValue;
        LastAliveTime = DateTime.Now;
        LoginRequestCancellationTokenSource = new CancellationTokenSource();
    }
    
    /// <summary>
    /// 创建登录凭据的实例。
    /// </summary>
    /// <param name="token">登录令牌。</param>
    /// <param name="accountInfo">登录账户信息。</param>
    public Credential(Guid token, AccountEx accountInfo) : this()   
    {
        Token = token;
        AccountInfo = accountInfo;
    }

    #endregion

    #region Properties
    
    /// <summary>
    /// 登录请求取消。
    /// </summary>
    internal CancellationTokenSource LoginRequestCancellationTokenSource { get; }

    /// <summary>
    /// 设置或返回当前凭据包含的令牌。
    /// </summary>
    [DataMember]
    public Guid Token { get; set; }

    /// <summary>
    /// 设置或返回当前凭据状态
    /// </summary>
    [DataMember]
    public CredentialState State { get; set; }
    
    /// <summary>
    /// 设置或返回最后一次激活时间。
    /// </summary>
    [DataMember]
    public DateTime LastAliveTime { get; set; }

    /// <summary>
    /// 设置或返回账户角色。
    /// </summary>
    [DataMember]
    public string RoleID { get; set; }
    
    /// <summary>
    ///  设置或返回登录的账户信息。
    /// </summary>
    [DataMember]
    public AccountEx AccountInfo { get; set; }

    /// <summary>
    /// 返回当前凭据对应客户端信息。
    /// </summary>
    [DataMember]
    public LoginClientInfo ClientInfo { get; set; }

    /// <summary>
    /// 设置或返回客户端IP地址。
    /// </summary>
    [DataMember]
    public string LoginIP { get; set; }

    /// <summary>
    /// 设置或返回客户端Port。
    /// </summary>
    [DataMember]
    public int LoginPort { get; set; }

    /// <summary>
    /// 设置或返回登录时间。
    /// </summary>
    [DataMember]
    public DateTime LoginTime { get; set; }

    /// <summary>
    /// 设置或返回登录结果描述。
    /// </summary>
    [DataMember]
    public string Description { get; set; }

    /// <summary>
    /// 返回空凭据。
    /// </summary>
    public static Credential Empty => new Credential();

    public static Credential ReadOnlyOne =>
        new Credential(Guid.Empty, new AccountEx("", "Read-Only", "", "", "", "", null));
    
    #endregion

    #region Methods

    /// <summary>
    /// 检查指定的凭据是否为空凭据。
    /// </summary>
    /// <param name="cred"></param>
    /// <returns></returns>
    public static bool IsEmpty(Credential cred)
    {
        return cred == null || cred.Token == Guid.Empty;
    }

    /// <inheritdoc />
    public override string ToString()
    {
        return $"{AccountInfo.LoginName}@{LoginIP}:{LoginPort}";
    }

    #endregion
    
}