using Microsoft.AspNetCore.Http;
using System;
using VCommon.Ioc;
using VCommon.VApplication;
using VCommon.VApplication.DataStore;

namespace VCommon.VOpenApi.VAspNetCore
{
    public class VAspNetCoreSession : IVSession, ISingletonIocClass
    {
        private const string AuthorizationHeader = "Authorization";
        private const string TokenHeaderPart = "Token";

        private readonly HttpContext _context;
        private readonly IUserStore _store;

        private bool _isTokenChecked;

        private Guid? _tenantId;
        private Guid? _userId;

        private string _token;

        internal VAspNetCoreSession(HttpContext context, IUserStore store)
        {
            _context = context;
            _store = store;
        }

        private void EnsureTokenCheck()
        {
            if (_isTokenChecked) return;

            string token = null;

            //从请求头获取 Token
            string rawToken;
            if (false == string.IsNullOrWhiteSpace(rawToken = _context.Request.Headers[AuthorizationHeader]))
            {
                var parts = rawToken.Split(' ');
                if (parts.Length == 2 && parts[0] == TokenHeaderPart && false == string.IsNullOrWhiteSpace(parts[1]))
                {
                    token = parts[1];
                }
            }

            //验证Token
            if (null != token)
            {
                _store.ValidateToken(token, out _tenantId, out var uid);
                _userId = uid;
                _token = token;
            }

            _isTokenChecked = true;
        }

        public Guid? UserId
        {
            get
            {
                EnsureTokenCheck();
                return _userId;
            }
        }

        public Guid? TenantId
        {
            get
            {
                EnsureTokenCheck();
                return _tenantId;
            }
        }

        public string Token
        {
            get
            {
                EnsureTokenCheck();
                return _token;
            }
        }

        public void DemandAuth()
        {
            EnsureTokenCheck();
            if (false == UserId.HasValue) throw new VApplicationAuthException("需要验证身份", AuthReason.AuthRequired);
        }
    }
}
