



using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Threading;
using System.Threading.Tasks;
using Aurora.Common.Entities;
using Aurora.Core.Domain.Entities;
using Aurora.Infrastructure.Tenant;
using Aurora.Infrastructure.User;
using Microsoft.EntityFrameworkCore;

namespace Aurora.Core.EntityFramework
{
    public class ApplicationDbContext : ApplicationReadonlyDbContext
    {
        protected readonly IUserContext _userContext;
        public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options
            , ITenantContextProvider currentTenantProvider
            , IUserContextProvider userContextProvider) : base(options, currentTenantProvider)
        {
            _userContext = userContextProvider.GetUserContext();
        }

        protected override void OnModelCreating(ModelBuilder builder)
        {

            base.OnModelCreating(builder);
        }

        public override int SaveChanges()
        {
            UpdateCommonFileds();
            return base.SaveChanges();
        }

        public override Task<int> SaveChangesAsync(CancellationToken cancellationToken = default(CancellationToken))
        {
            UpdateCommonFileds();
            return base.SaveChangesAsync(cancellationToken);
        }

        /// <summary>
        /// 数据新增、更新前更新公共字段
        /// </summary>
        private void UpdateCommonFileds()
        {
            var nowTime = DateTimeOffset.Now;
            foreach (var entry in this.ChangeTracker.Entries<TenantEntityBase>().Where(x => x.State == EntityState.Added || x.State == EntityState.Modified))
            {
                var entity = entry.Entity;
                switch (entry.State)
                {
                    case EntityState.Added:
                        entity.TenantCode = _tenantContext.TenantCode;
                        entity.CreateTime = nowTime;
                        entity.CreateUserName = _userContext.UserName;
                        break;
                    case EntityState.Modified:
                        entity.ModifyTime = nowTime;
                        entity.ModifyUserName = _userContext.UserName;
                        break;
                }
            }
            this.ChangeTracker.DetectChanges();
        }


    }
}