using System;
using System.Collections.Concurrent;
using System.IO;
using System.Text;
using System.Threading;
using MrWu.Debug;
using Server.Core;
using Server.DB.Redis;

namespace GameDAL.FriendRoom
{
    public class FightDataManager : SingleInstance<FightDataManager>
    {
        private Thread thead;

        private bool IsDispose = false;
        
        private const string dirPath = "fightData";
        
        private ConcurrentQueue<FightDataCommand> CommandQueue = new ConcurrentQueue<FightDataCommand>();
        
        public FightDataManager()
        {
            if (!Directory.Exists(dirPath))
            {
                Directory.CreateDirectory(dirPath);
            }
            
            thead = new Thread(Run);
            thead.Start();
        }

        private string OldFileName(string weiyima)
        {
            return $"{dirPath}/{weiyima}";
        }

        private string NewFileName(string weiyima)
        {
            return $"{dirPath}/{weiyima}.bytes";
        }

        private string TempFileName(string weiyima)
        {
            return $"{dirPath}/{weiyima}.temp";
        }
        
        public byte[] LoadFightData(string weiyima,out bool isOld)
        {
            byte[] result = null;
            try
            {
                isOld = false;
                string fileName = NewFileName(weiyima);
                if (File.Exists(fileName))
                {
                    result = File.ReadAllBytes(fileName);
                    Debug.Info("加载战斗数据!" + weiyima);
                }else
                {
                    //旧文件
                    fileName = OldFileName(weiyima);
                    if (File.Exists(fileName))
                    {
                        string jsonData = File.ReadAllText(fileName);
                        isOld = true;
                        return Encoding.UTF8.GetBytes(jsonData);
                    }
                }
            }
            catch (Exception e)
            {
                Debug.Error($"读取战绩还能报错?? {e.Message}");
                throw;
            }

            return result;
        }

        public void SaveFightData(string weiyima,byte[] data)
        {
            CommandQueue.Enqueue(FightDataCommand.Create(Command.Save, weiyima, data));
        }

        public void DelFightData(string weiyima)
        {
            CommandQueue.Enqueue(FightDataCommand.Create(Command.Del, weiyima));
        }

        private void Run()
        {
            #if DEBUG
            uint threadId = ThreadHelper.GetOSThreadId();
            Debug.Info($"ThreadStart FightDataManager {threadId}");
            #endif
            
            while (true)
            {
                if (CommandQueue.TryDequeue(out FightDataCommand command))
                {
                    try
                    {
                        string fileName = NewFileName(command.WeiYiMa);
                        string tempFileName = TempFileName(command.WeiYiMa);

                        switch (command.Command)
                        {
                            case Command.Save:
                                //保证文件的原子性，存到临时文件，再移动到正式文件
                                File.WriteAllBytes(tempFileName,command.Data);
                                if (File.Exists(fileName))
                                {
                                    File.Delete(fileName);
                                }
                                File.Move(tempFileName,fileName);
                                break;
                            case Command.Del:
                                File.Delete(fileName);
                                break;
                        } 
                    }
                    catch (Exception e)
                    {
                        Debug.Error($"执行战斗数据指令报错:{command.Command} {command.WeiYiMa} {e.Message}");
                    }
                    
                    ReferencePool.Recycle(command);
                }
                else
                {
                    //如果关闭了，就退出
                    if (IsDispose)
                    {
                        break;
                    }
                }

                Thread.Sleep(1);
            }
        }

        public void Dispose()
        {
            IsDispose = true;
            thead.Join();
        }

        public class FightDataCommand : Reference
        {
            public string WeiYiMa;
            public byte[] Data;
            public Command Command;
            
            

            public static FightDataCommand Create(Command command,string weiyima,byte[] data= null)
            {
                FightDataCommand fightDataCommand = ReferencePool.Fetch<FightDataCommand>();
                fightDataCommand.WeiYiMa = weiyima;
                fightDataCommand.Data = data;
                fightDataCommand.Command = command;
                return fightDataCommand;
            }

            public override void Dispose()
            {
                WeiYiMa = null;
                Data = null;
                ReferencePool.Recycle(this);
            }
        }
        
        public enum Command
        {
            /// <summary>
            /// 保存
            /// </summary>
            Save,
            /// <summary>
            /// 加载
            /// </summary>
            Del,
        }
        
    }
}