using System.IO;
using Thousandto.Update.Enum;
using Thousandto.Update.Log;
using Thousandto.Update.Trans;
using Thousandto.Update.Xml;

namespace Thousandto.Update.Flow
{
    /// <summary>
    /// 1. 资源转移,从客户端中释放资源到指定存储位置
    /// a. IOS如果包内有资源,启动的时候不做资源释放
    /// b. 安卓启动的时候判断是否需要释放资源
    /// c. PC版本不做资源释放
    /// d. 如果存储位置没有资源,同时app内LocalVersion的分段资源号是0,则强制释放资源
    /// e. 如果远端的补丁版本比本地补丁版本更高,则判断是否需要释放资源
    /// </summary>
    public class Flow1TransResource : BaseFlow
    {
        //平台类型
        private PlatformType _platformType;
        //资源转移功能实例
        TransResource _transInstance;

        /// <summary>
        /// 强制转移资源
        /// 1. ios在进入游戏后有资源更新,会返回到更新界面做资源转移
        /// 2. 
        /// </summary>
        private bool _forceTrans = false;

        public void SetExternalData(string sourcePath, PlatformType type, Thousandto.Update.Delegate.TransResourceFinishCallback transFinishCallback = null)
        {
            _platformType = type;

            switch (_platformType)
            {
                case PlatformType.Android:
                    _transInstance = new TransAndroidResource();
                    break;
                case PlatformType.IOS:
                    _transInstance = new TransIOSResource();
                    break;
                case PlatformType.Windows:
                    _transInstance = new TransPCResource();
                    break;
                default:
                    _transInstance = new TransPCResource();
                    break;
            }

            //非全转移
            _transInstance.IsUnZipObb = false;
            UpdateLog.DEBUG_LOG("Transform source:" + sourcePath);
            _transInstance.SetUnzipPath(sourcePath, _storeDir, transFinishCallback);
        }

        public void ReInitTransData()
        {
            if (_transInstance != null)
                _transInstance.ReInit();
        }

        //强制转移资源,因为要更新资源,不管是基础资源还是补丁资源
        public void ForceTransWhenNeedUpdate()
        {
            _forceTrans = true;
        }

        //强制做资源释放, 在ios通过游戏内更新分段资源时调用
        public void SetForceUnzip()
        {
            _forceTrans = true;
        }

        public override void OnEnter(BaseFlow oldFlow)
        {
            base.OnEnter(oldFlow);

            //转移过资源,xml就从storePath取。否则从包内取
            ChangeLocalXmlPath(HasTransedResource());
        }

        public override int Work()
        {
            if (!CheckLastFlowResult()) return LastFlowResult;

            int ret = CodeDefine.RET_INIT;
            if (!checkNeedTrans())
            {
                ret = CodeDefine.RET_SUCCESS;
            }
            else
            {
                //如果有老的xml,需要先保存数据
                LocalVersionXml oldXml = getOldXmlData(_storedLocalXmlPath);

                //转移资源完成后调用
                _transInstance.SetInternalCallback(() =>
                {
                    //将老数据:分段版本、补丁版本、app版本填充的新的xml中
                    updateLocalXmlData(oldXml, _storedLocalXmlPath, true, _inAppClientVersion);
                });

                _transInstance.StartUnzipByThread();

                bool success = _transInstance.GetTransReslult();

                //转移资源后,改变LocalXml的读取路径
                ChangeLocalXmlPath(true);

                ret = success ? CodeDefine.RET_SUCCESS : CodeDefine.RET_FAIL_TRANS_FAIL;

                //打点转移资源
                Recorder.StepRecorder.AddStep(Recorder.StepType.TransResource, success ? 0 : 1, success.ToString());

                _transInstance.CallFinish(success);
                _forceTrans = false;
            }
            return ret;
        }

        public override void Uninitialize()
        {
            LocalXml = null;
        }

        public override void GetCurDownInfo(out string url, out int total, out int downloaded)
        {
            base.GetCurDownInfo(out url, out total, out downloaded);
            url = "";
            total = _transInstance.GetTotalValue();
            downloaded = _transInstance.GetCurrentProgress();
        }

        public void TransResourceFinish(bool result)
        {

        }

        //判断是否需要转移资源
        private bool checkNeedTrans()
        {
            UpdateLog.DEBUG_LOG("检查是否需要转移资源");
            bool ret = false;
            LocalVersionXml localXml = getOldXmlData(_storedLocalXmlPath);
            string storedAppVersion = localXml == null ? "" : localXml.LocalAppVersion;
            string hasCopy = localXml == null ? "" : localXml.HasCopy;

            //存储的app版本号不存在(没释放过资源, 本地LocalVersion.xml不存在)
            if (string.IsNullOrEmpty(storedAppVersion))
            {
                if (_inAppBaseVersion == "0")
                {
                    //同时包内分段号为0,则说明是下载器,需要强制释放资源
                    ret = true;
                    UpdateLog.DEBUG_LOG("inAppBaseVerson==0,需要强制转移资源");
                }
                else if (_platformType == PlatformType.IOS && !_forceTrans)
                {
                    if (!File.Exists(_storedLocalXmlPath))
                    {
                        _storedLocalXmlPath = _storedLocalXmlPath.Replace("\\", "/");
                        string dir = _storedLocalXmlPath.Substring(0, _storedLocalXmlPath.LastIndexOf("/"));
                        if (!Directory.Exists(dir))
                            Directory.CreateDirectory(dir);
                        File.Copy(_inAppLocalXmlPath, _storedLocalXmlPath);
                    }

                    string inAppXmlAppVer = getIOSAppVerInXml(_storedLocalXmlPath);
                    if (!string.IsNullOrEmpty(inAppXmlAppVer) && CompareVersionFormat(_inAppClientVersion, inAppXmlAppVer) > 0) 
                    {
                        ret = true;
                        UpdateLog.DEBUG_LOG("IOS平台,包内版本比包内xml中app版本更高,需要转移资源");
                    }
                    else
                    {
                        //没释放过资源,并且是ios平台,分段号又不为0,说明包内有资源可以运行,不做资源释放
                        ret = false;
                        UpdateLog.DEBUG_LOG("游戏启动,IOS平台,跳过转移资源");
                    }
                }
                else
                {
                    ret = true;
                    UpdateLog.DEBUG_LOG("需要转移资源");
                }
            }
            else if ((_platformType != PlatformType.IOS && hasCopy.ToLower() != _hasCopyTag))
            {
                ret = true;
                UpdateLog.DEBUG_LOG("上次转移失败,需要重新转移资源");
            }
            else if(CompareVersionFormat(_inAppClientVersion, storedAppVersion) > 0)
            {
                //客户端版本比存储的版本更高,需要删除之前释放出去的资源,并且更新_repairRecords
                ret = true;
                Manager.UpdateManager.Instance.DelelteReleasedFiles();
                //将转移资源的本地标签置为false
                updateLocalXmlData(null, _storedLocalXmlPath, false, null);
            }
            else
                UpdateLog.DEBUG_LOG("不需要转移资源");

            //ios平台,并且storeXmlPath存在,则切换localXml的读取路径
            if (_platformType == PlatformType.IOS && File.Exists(_storedLocalXmlPath))
                ChangeLocalXmlPath(true);

            return ret;
        }

        private LocalVersionXml getOldXmlData(string oldXmlPath)
        {
            LocalVersionXml xml = null;
            if (File.Exists(oldXmlPath))
            {
                xml = new LocalVersionXml();
                xml.parseLocalVersionXml(oldXmlPath);
            }

            return xml;
        }

        private string getIOSAppVerInXml(string localXmlPath)
        {
            string appVer = "";
            if (!string.IsNullOrEmpty(localXmlPath) && File.Exists(localXmlPath))
            {
                var xml = new LocalVersionXml();
                xml.parseLocalVersionXml(localXmlPath);
                appVer = xml.LocalAppVersion;
            }

            return appVer;
        }

        private void updateLocalXmlData(LocalVersionXml oldXml, string newXmlPath, bool transed, string appVersion)
        {
            if (File.Exists(newXmlPath))
            {
                LocalVersionXml newXml = new LocalVersionXml();
                newXml.parseLocalVersionXml(newXmlPath);
                if (oldXml != null)
                {
                    newXml.save(oldXml.BaseResVersion, oldXml.PatchResVersion, "", appVersion);
                }

#if !UNITY_EDITOR
                UpdateLog.DEBUG_LOG("更新LocalXmlData数据:transed = " + transed + "_hasCopyTag = " + _hasCopyTag);
                if (transed)
                {
                    newXml.save("", "", _hasCopyTag);
                }
                else
                    newXml.save("", "", "no");
#endif
            }
        }
    }
}