/**
 * @file    ExternalDependencyLoader.cs
 * 
 * @author  jschoi
 * @date    2024~
 * @copyright Copyright © Com2uS Platform Corporation. All Right Reserved.
 * @defgroup Hive.Unity.Editor
 * @{
 * @brief HIVE External Dependency 로컬 경로 동기화 <br/><br/>
 */

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using System;
using System.IO;
using System.ComponentModel;
using System.Reflection;
using System.Xml;
using System.Linq;

namespace Hive.Unity.Editor
{    
    using ExternalDependencyDictionary = Dictionary<ExternalDependencyType, bool>;
    using ExternalDependencySerializableDictionary = SerializableDictionary<string, bool>;

    [InitializeOnLoad]
    public class ExternalDependencyLoader
    {
        static ExternalDependencyLoader()
        {
            // Hive Sample 빌드 프로젝트가 아닌 경우만 동기화
            if(!ExternalDependencyUtil.isSampleBuild())
            {
                // HiveSDK 버전 업데이트로 더이상 사용하지 않는 '디펜던시 xml'이나 '기타 설정 파일' 제거
                removeDeprecatedFiles();              

                // HiveSDK 업데이트 한 경우
                // - HiveSDKSettingsDependencies.xml에 설정된 HiveSDK 버전 업데이트
                // - HiveSDKSettingsDependencies.xml가 없는 경우 TempHiveSDKSettingsDependencies.xml(디폴트 파일)의 HiveSDK 버전 업데이트
                updateHiveDependenciesXmlVersion();
            }
        }

        // 파일 삭제 (HiveSDK 업데이트 과정에서 더이상 사용하지 않는 파일 포함)
        private static void removeDeprecatedFiles()
        {
            HiveLogger.Log(String.Format("[ExternalDependencyLoader] removeDeprecatedFiles"));

            // (1) ExternalDependencyType에서 제거된 미사용 **Dependencies.xml 제거 (+ 구버전 셋팅 저장 세이브 파일(HiveEditorSettings.txt) 제거)
            string[] removeFileList = {"../ProjectSettings/HiveEditorSettings.txt",     // 23.0.0 업데이트 시 Hive Dependenices 저장 유도 팝업 노출 시간 저장된 파일 제거, (해당 팝업을 23.4.0 부터 사용하지 않음)
                                        "Hive_SDK_v4/Dependencies/HIVESDK_MarketFacebookCloudDependencies.xml",     // 24.2.0, Facebook Cloud 관련 디펜던시 파일 제거 
                                        "Hive_SDK_v4/Dependencies/HIVESDK_ProviderFacebookCloudDependencies.xml",
                                        "Hive_SDK_v4/Dependencies/HIVESDK_PushFacebookCloudA2uDependencies.xml",
                                        "Hive_SDK_v4/Dependencies/HIVESDK_DefaultDependencies.xml",
                                        "Hive_SDK_v4/Dependencies/HIVESDKDependencies.xml",
                                        "Hive_SDK_v4/Editor/HIVESDK_MarketFacebookCloudDependencies.xml",
                                        "Hive_SDK_v4/Editor/HIVESDK_PushFacebookCloudA2uDependencies.xml",
                                        "Hive_SDK_v4/Editor/HIVESDK_ProviderFacebookCloudDependencies.xml",
                                        "Hive_SDK_v4/Editor/HIVESDK_DefaultDependencies.xml",
                                        "Hive_SDK_v4/Editor/HIVESDKDependencies.xml" };

            foreach(string removeFile in removeFileList)
            {
                string path = Path.Combine(Application.dataPath, removeFile);

                if (File.Exists(path))
                {
                    try
                    {
                        File.Delete(path);
                        HiveLogger.Log(String.Format("[ExternalDependencyLoader] removeDeprecatedFiles, path : " + path));
                    }
                    catch (Exception e)
                    {
                        HiveLogger.Log(String.Format("[ExternalDependencyLoader] removeDeprecatedFiles, File.Delete({0}) Exception. \n {1}", path, e.ToString()));
                    }
                }
            }

            // (2) HiveSDKSettingsDependencies.xml 사용으로 미사용하게된 **Dependencies.xml 제거 (ExternalDependenciesType에 정의된)
            DirectoryInfo editorDirInfo = new DirectoryInfo(ExternalDependencyConst.editorPath);
            DirectoryInfo dependenciesDirInfo = new DirectoryInfo(ExternalDependencyConst.dependenciesPath);

            foreach(ExternalDependencyType t in Enum.GetValues(typeof(ExternalDependencyType)))
            {
                if(Directory.Exists(ExternalDependencyConst.editorPath))
                {
                    foreach(FileInfo f in editorDirInfo.GetFiles())
                    {
                        if(f.Name.Contains(ExternalDependencyUtil.getEnumDescription(t) + "Dependencies.xml"))
                        {
                            HiveLogger.Log(String.Format("[ExternalDependencyLoader] removeFile (/Editor path), remove : ~" + ExternalDependencyUtil.getEnumDescription(t) + "Dependencies.xml"));
                            f.Delete(); // .xml 및 .meta 제거
                        }
                    }
                }
                if(Directory.Exists(ExternalDependencyConst.dependenciesPath))
                {
                    foreach(FileInfo f in dependenciesDirInfo.GetFiles())
                    {
                        if(f.Name.Contains(ExternalDependencyUtil.getEnumDescription(t) + "Dependencies.xml"))
                        {
                            HiveLogger.Log(String.Format("[ExternalDependencyLoader] removeFile (/Dependencies path), remove : ~" + ExternalDependencyUtil.getEnumDescription(t) + "Dependencies.xml"));
                            f.Delete(); // .xml 및 .meta 제거
                        }
                    }
                }
            }
        }

        // HiveSDK Unity 패키지 업데이트 시 디펜던시 파일 내 적용된 HiveSDK 버전 업데이트 (HiveSDK v4 25.2.0)
        private static void updateHiveDependenciesXmlVersion() {

            // 개발자가 직접 저장한 디펜던시 파일 존재 여부에 따라 관리할 디펜던시 파일을 확인
            if(File.Exists(ExternalDependencyConst.hiveDependenciesXmlPath)) {
                if(File.Exists(ExternalDependencyConst.hiveDependenciesTempXmlPath)) {
                    // 개발자가 디펜던시를 저장해서 사용하고 있으며 && Hive Unity 패키지를 업데이트한 상황

                    // Save 상태를 불러와 현재 HiveSDK 버전으로 업데이트
                    ExternalDependencyDictionary androidDependency = ExternalDependencyDictionaryManager.LoadExternalDependencyDictionary(ExternalDependencyDictionaryManager.SupportOSType.Android);
                    ExternalDependencyDictionary iosDependency = ExternalDependencyDictionaryManager.LoadExternalDependencyDictionary(ExternalDependencyDictionaryManager.SupportOSType.iOS);
                    Dictionary<ExternalDependencyDictionaryManager.SupportOSType, Dictionary<ExternalDependencyType, bool>> osDependency = new Dictionary<ExternalDependencyDictionaryManager.SupportOSType, Dictionary<ExternalDependencyType, bool>>();
                    osDependency[ExternalDependencyDictionaryManager.SupportOSType.Android] = androidDependency;
                    osDependency[ExternalDependencyDictionaryManager.SupportOSType.iOS] = iosDependency;
                    ExternalDependencyDictionaryManager.createHiveSDKSettingsDependenciesXmlFile(osDependency);

                    // 디폴트 디펜던시 제거 (Assets/Hive_SDK_v4/Editor/TempHiveSDKSettingsDependencies.xml)
                    // 해당 파일을 제거하면서 업데이트를 1회성으로 진행 (잦은 반복처리 하지 않도록)
                    File.Delete(ExternalDependencyConst.hiveDependenciesTempXmlPath);
                }
            }
            else {
                // 버전 업데이트 (Assets/Hive_SDK_v4/Editor/TempHiveSDKSettingsDependencies.xml)
                setHiveVerInPackageDefaultSettingsDependenciesXML();
            }
        }

        // Hive Unity 패키지에서 전달된 디폴트 TempHiveSDKSettingsDependencies.xml이 버전값이 없는 초기상태인 경우
        // 현재 패키지의 Hive 버전값으로 변경하도록 처리
        private static void setHiveVerInPackageDefaultSettingsDependenciesXML() {
            // 파일 유무 확인
            if (File.Exists(ExternalDependencyConst.hiveDependenciesTempXmlPath)) {
                string tmpHiveDependenciesTempXmlPath = Path.Combine(Application.dataPath, "Hive_SDK_v4/Editor/tmpTempHiveSDKSettingsDependencies.xml");
                if (File.Exists(tmpHiveDependenciesTempXmlPath))
                {
                    File.Delete(tmpHiveDependenciesTempXmlPath);
                }

                IEnumerable<string> lines = null;
                // 반복 체크를 최소화하기 위한 검수 문자열
                string lineCheckedString = "<!--HiveSDK version already checked-->";

                try {
                    lines = File.ReadAllLines(ExternalDependencyConst.hiveDependenciesTempXmlPath);
                    if(lines.First().Contains(lineCheckedString)) {
                        // 검수 문자열 확인, 이미 검수된 xml 파일이므로 종료
                        HiveLogger.Log(String.Format("[ExternalDependencyLoader] setHiveVerInPackageDefaultSettingsDependenciesXML, version already checked"));
                        return;
                    }

                    StreamWriter writer = File.CreateText(tmpHiveDependenciesTempXmlPath);   
                    IEnumerator ienum = lines.GetEnumerator();                    

                    // 반복 체크하지 않게 첫 라인에 검수 문자열 추가
                    writer.WriteLine(lineCheckedString);
                    while(ienum.MoveNext()) {
                        string line = (string)ienum.Current;

                        // 정의된 키워드를 Hive 버전으로 변경
                        if(line.Contains("{Hive_SDK_Version}")) {
                            line = line.Replace("{Hive_SDK_Version}", ExternalDependencyConst.getInterfaceDependencyVersion());
                        }

                        writer.WriteLine(line);
                    }

                    writer.Flush();
                    writer.Close();

                    // 원본 파일 제거 후 사본을 원본으로 교체
                    File.Delete(ExternalDependencyConst.hiveDependenciesTempXmlPath);
                    File.Move(tmpHiveDependenciesTempXmlPath, ExternalDependencyConst.hiveDependenciesTempXmlPath);

                } catch (Exception ex) {
                    HiveLogger.Log(String.Format("[ExternalDependencyLoader] setHiveVerInPackageDefaultSettingsDependenciesXML exception : " + ex.ToString()));
                }
            }
        }
    }
}
