/**
 * @file    ExternalDependencyManager.cs
 * 
 * @date    2020-2024
 * @copyright Copyright © Com2uS Platform Corporation. All Right Reserved.
 */

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using System;
using System.IO;
using System.Xml;
using System.Text;

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

    public class ExternalDependencyDictionaryManager
    {      
        // Xml Tag Name
        private static string XML_Tag_HiveDependencies = "HiveDependencies";
        private static string XML_Tag_UpdatedInfo = "UpdatedInfo";

        // Xml Attribute Name
        private static string XML_Attr_Include = "include";
        private static string XML_Attr_Android = "Android";
        private static string XML_Attr_iOS = "iOS";
        private static string XML_Attr_Version = "version";

        // ExternalDependencyEditor OnGUI 갱신 시 참조할 임시 데이터
        private static ExternalDependencyDictionary tempEditorAndroidDepend;
        private static ExternalDependencyDictionary tempEditoriOSDepend;

        // 구 버전 저장 파일 마이그레이션 지원 범위
        // - ExternalDependencyType 내 provider가 추가되거나 삭제된 경우 신규 enum value를 추가하여 작성합니다.
        //   - 추가된 provider가 true로 마이그레이션 되어야하는 경우 작성 필요 (미작성 시 기본 false)
        //   - 삭제된 provider는 이제 동작하지 않도록 false 되어야하므로 작성 필요
        private enum SaveDataVersionType
        {
            Hive4161000,
            Hive4230000,
            Hive4230400,
            Hive4250000,
        }

        // 디펜던시(ExternalDependencyDictionary) 설정으로 지원되는 OS 타입 
        public enum SupportOSType {
            Android,
            iOS
        }

       
        public static ExternalDependencyDictionary LoadExternalDependencyDictionary(SupportOSType osType)
        {
            HiveLogger.Log(String.Format("[ExternalDependencyDictionaryManager] LoadExternalDependencyDictionary"));

            var dictionary = new ExternalDependencyDictionary();
            Reset(osType, ref dictionary);

            dictionary = LoadSavedFiles(osType, dictionary);

            return dictionary;
        }

        /**
         * HiveSDK 구 버전에서 사용하던 Save 파일이 있다면 최신 형태로 변경합니다.
         * (HiveSDK v4 25.0.0에서 ExternalDependencyConst.jsonDataPath, ExternalDependencyConst.legacyJsonDataPath 해당하는 탐색 로직 제거)
         */
        private static ExternalDependencyDictionary migrateLegacySaveData(SaveDataVersionType type, SupportOSType osType, ExternalDependencyDictionary dictionary)
        {
            switch(type)
            {
                case SaveDataVersionType.Hive4161000:
                    return migrateJsonDataToHive4161000Type(dictionary);
                case SaveDataVersionType.Hive4230000:
                    return migrateJsonDataToHive4230000Type(dictionary);
                case SaveDataVersionType.Hive4230400:
                    return migrateSaveDataToHive4230400Type(osType, dictionary);
                case SaveDataVersionType.Hive4250000:
                    return migrateSaveDataToHive4250000Type(dictionary);
                default:
                    return dictionary;
            }
        }

        private static ExternalDependencyDictionary LoadSavedFiles(SupportOSType osType, ExternalDependencyDictionary dictionary)
        {
            if (File.Exists(ExternalDependencyConst.jsonDataPath) || File.Exists(ExternalDependencyConst.legacyJsonDataPath)) {
                dictionary = migrateLegacySaveData(SaveDataVersionType.Hive4161000, osType, dictionary);
                dictionary = migrateLegacySaveData(SaveDataVersionType.Hive4230000, osType, dictionary);
            }
            else if (File.Exists(ExternalDependencyConst.projSettingsJsonDataPath)) {
                dictionary = migrateLegacySaveData(SaveDataVersionType.Hive4230000, osType, dictionary);
            }

            dictionary = migrateLegacySaveData(SaveDataVersionType.Hive4230400, osType, dictionary);
            dictionary = migrateLegacySaveData(SaveDataVersionType.Hive4250000, osType, dictionary);

            return dictionary;
        }

        private static ExternalDependencyDictionary migrateSaveDataToHive4250000Type(ExternalDependencyDictionary dictionary)
        {
            HiveLogger.Log(String.Format("[ExternalDependencyDictionaryManager] migrateSaveDataToHive4250000Type"));

            var tmpDictionary = new ExternalDependencyDictionary();
            tmpDictionary = dictionary;
            tmpDictionary[ExternalDependencyType.AdjustSignatureV3] = false;        // removed Hive 25.0.0, always return false

            return tmpDictionary;
        }

        private static ExternalDependencyDictionary migrateSaveDataToHive4230400Type(SupportOSType osType, ExternalDependencyDictionary dictionary)
        {
            // ~ Hive SDK 23.4.x 이상 타입으로 마이그레이션 처리 (use 'xml format' save file)
            HiveLogger.Log(String.Format("[ExternalDependencyDictionaryManager] migrateSaveDataToHive4230400Type"));

            var tmpDictionary = new ExternalDependencyDictionary();

            if(File.Exists(ExternalDependencyConst.projSettingsXmlDataPath))
            {
                // Hive SDK 23.4.x 이상 타입 세이브 파일이 있는 경우
                // 파일 내용 반환
                HiveLogger.Log("[ExternalDependencyDictionaryManager] migrateSaveDataToHive4230400Type, exist 4230400Type");
                tmpDictionary = LoadSavedXmlData(ExternalDependencyConst.projSettingsXmlDataPath, osType, dictionary);
            }
            else
            {
                // Hive SDK 23.4.x 이상 타입 세이브 파일이 없는 경우
                // 23.4.0 타입 마이그레이션 default 값 설정 
                HiveLogger.Log("[ExternalDependencyDictionaryManager] migrateSaveDataToHive4230400Type, not exist 4230400Type");
                tmpDictionary = dictionary;


                tmpDictionary[ExternalDependencyType.MarketHiveStore] = true;
                tmpDictionary[ExternalDependencyType.AnalyticsConsentMode] = true;

            }
            
            return tmpDictionary;
        }

        private static ExternalDependencyDictionary migrateJsonDataToHive4230000Type(ExternalDependencyDictionary dictionary)
        {
            // ~ Hive SDK 23.0.0 마이그레이션 처리 (use 'json format' save file)
            HiveLogger.Log(String.Format("[ExternalDependencyDictionaryManager] migrateJsonDataToHive4230000Type"));

            var tmpDictionary = new ExternalDependencyDictionary();
            
            if (File.Exists(ExternalDependencyConst.projSettingsJsonDataPath))
            {
                // Hive SDK 23.0.0 타입 세이브 파일이 있는 경우
                // 파일 내용 반환
                HiveLogger.Log("[ExternalDependencyDictionaryManager] migrateJsonDataToHive4230000Type, exist 4230000Type");
                tmpDictionary = LoadSavedLegacyData(ExternalDependencyConst.projSettingsJsonDataPath);
            }
            else
            {
                // Hive SDK 23.0.0 타입 세이브 파일이 없는 경우
                // 23.0.0 타입 마이그레이션 default 값 설정 
                HiveLogger.Log("[ExternalDependencyDictionaryManager] migrateJsonDataToHive4230000Type, not exist 4230000Type");
                tmpDictionary = dictionary;

                bool useProviderGoogle = false;
                foreach (KeyValuePair<ExternalDependencyType, bool> pair in tmpDictionary)
                {
                    if(pair.Key.Equals(ExternalDependencyType.Google))
                    {
                        HiveLogger.Log(String.Format("[ExternalDependencyDictionaryManager] migrateJsonDataToHive4230000Type, saved ProviderGoogle : " + pair.Value));
                        useProviderGoogle = pair.Value;
                    }
                }

                // 23.0.0 업데이트 시 추가된 타입의 기본 default : true 처리 필요한 타입
                tmpDictionary[ExternalDependencyType.Apple] = true; 
                tmpDictionary[ExternalDependencyType.AppleSignIn] = true;
                tmpDictionary[ExternalDependencyType.HiveMembership] = true;  
                tmpDictionary[ExternalDependencyType.HivePromotion] = true;
                tmpDictionary[ExternalDependencyType.GoogleInAppReview] = true;                        
                tmpDictionary[ExternalDependencyType.HiveDeviceManagement] = true;                        
                tmpDictionary[ExternalDependencyType.HiveRealNameVerification] = true;
                tmpDictionary[ExternalDependencyType.GoogleInAppUpdate] = true;
                tmpDictionary[ExternalDependencyType.DataStore] = true; 
                tmpDictionary[ExternalDependencyType.PushGoogleFcm] = true;
                tmpDictionary[ExternalDependencyType.MarketApple] = true;                       
                tmpDictionary[ExternalDependencyType.MarketGoogle] = true;
                tmpDictionary[ExternalDependencyType.HiveAdultConfirm] = true;
                tmpDictionary[ExternalDependencyType.HiveIdentityVerification] = true;
                
                // 23.0.0 업데이트 시 추가된 타입의 기본 default : false 처리 필요한 타입
                // tmpDictionary[ExternalDependencyType.FacebookCloud] = false;             // 24.2.0 이상 적용 시 더이상 사용하지 않는 셋팅 (FacebookCloud deprecated)
                // tmpDictionary[ExternalDependencyType.PushFacebookCloudA2u] = false;      // 24.2.0 이상 적용 시 더이상 사용하지 않는 셋팅 (FacebookCloud deprecated)
                tmpDictionary[ExternalDependencyType.PushAmazonAdm] = false;
                tmpDictionary[ExternalDependencyType.MarketAmazon] = false;
                // tmpDictionary[ExternalDependencyType.MarketFacebookCloud] = false;       // 24.2.0 이상 적용 시 더이상 사용하지 않는 셋팅 (FacebookCloud deprecated)
                tmpDictionary[ExternalDependencyType.MarketSamsung] = false;
                tmpDictionary[ExternalDependencyType.MarketHuawei] = false;
                tmpDictionary[ExternalDependencyType.MarketOneStore] = false;
                tmpDictionary[ExternalDependencyType.MarketLebi] = false;
                tmpDictionary[ExternalDependencyType.MarketXiaomi] = false;
                tmpDictionary[ExternalDependencyType.HiveAgeRangeAmazon] = false;
                tmpDictionary[ExternalDependencyType.HiveAgeRangeApple] = false;
                tmpDictionary[ExternalDependencyType.HiveAgeRangeGoogle] = false;

                // 23.0.0 업데이트 시 추가된 타입의 조건에 따른 true/false 처리
                if(useProviderGoogle)
                {
                    HiveLogger.Log(String.Format("[ExternalDependencyDictionaryManager] migrateJsonDataToHive4230000Type, set ProviderGooglePlayGames : true"));
                    tmpDictionary[ExternalDependencyType.GooglePlayGames] = true;
                }
                else {
                    HiveLogger.Log(String.Format("[ExternalDependencyDictionaryManager] migrateJsonDataToHive4230000Type, set ProviderGooglePlayGames : false"));
                    tmpDictionary[ExternalDependencyType.GooglePlayGames] = false;
                }
            }

            return tmpDictionary;
        }

        private static ExternalDependencyDictionary migrateJsonDataToHive4161000Type(ExternalDependencyDictionary dictionary)
        {
            // ~Hive SDK v4.16.1 마이그레이션 처리 (use 'json format' save file)
            HiveLogger.Log(String.Format("[ExternalDependencyDictionaryManager] migrateJsonDataToHive4161000Type"));
            
            if (File.Exists(ExternalDependencyConst.legacyJsonDataPath))
            {
                string jsonDataString = File.ReadAllText(ExternalDependencyConst.legacyJsonDataPath);
                ExternalDependencySerializableDictionary serializableDictionary = JsonUtility.FromJson<ExternalDependencySerializableDictionary>(jsonDataString);

                foreach (KeyValuePair<string, bool> pair in serializableDictionary)
                {
                    int i = 0;
                    bool isNumbericKey = int.TryParse(pair.Key, out i);

                    if(isNumbericKey)
                    {   
                        string legacyName = Enum.GetName(typeof(LegacyExternalDependencyType), i);
                        ExternalDependencyType externalDependencyType;
                        if (Enum.TryParse(legacyName, out externalDependencyType))
                        {
                            if (Enum.IsDefined(typeof(ExternalDependencyType), externalDependencyType))
                            {
                                dictionary[externalDependencyType] = pair.Value;
                            }
                            else
                            {
                                HiveLogger.Log(String.Format("[ExternalDependencyDictionaryManager] migrateJsonDataToHive4161000Type, {0} is not an underlying value of the ExternalDependencyType enumeration.", pair.Key));
                                continue;
                            }
                        }
                        else
                        {
                            HiveLogger.Log(String.Format("[ExternalDependencyDictionaryManager] migrateJsonDataToHive4161000Type, {0} is not a member of the ExternalDependencyType enumeration.", pair.Key));
                            continue;
                        }
                    }
                    else
                    {
                        HiveLogger.Log(String.Format("[ExternalDependencyDictionaryManager] migrateJsonDataToHive4161000Type, {0} is broken.", ExternalDependencyConst.legacyJsonDataPath));
                    }
                }
            }
            else if (File.Exists(ExternalDependencyConst.jsonDataPath))
            {
                dictionary = LoadSavedLegacyData(ExternalDependencyConst.jsonDataPath);
            }

            return dictionary;
        }


        public static bool isUseDependency(SupportOSType osType, ExternalDependencyType type) {
            // 저장된 xml 데이터에서 사용중 여부 확인
            // (저장된 데이터가 없는 경우 더이상 reset()을 통해 default를 생성하지 않음, Hive 23.0.0)
            var dictionary = new ExternalDependencyDictionary();
            dictionary = LoadSavedXmlData(ExternalDependencyConst.projSettingsXmlDataPath, osType, dictionary);

            foreach(KeyValuePair<ExternalDependencyType, bool> pair in dictionary)
            {
                if(pair.Key == type)
                {
                    return pair.Value;
                }
            }
            return false;
        }

        private static ExternalDependencyDictionary LoadSavedLegacyData(string filePath) {
            HiveLogger.Log(String.Format("[ExternalDependencyDictionaryManager] LoadSavedLegacyData"));

            var dictionary = new ExternalDependencyDictionary();

            if (File.Exists(filePath))
            {
                string jsonDataString = File.ReadAllText(filePath);
                ExternalDependencySerializableDictionary serializableDictionary = JsonUtility.FromJson<ExternalDependencySerializableDictionary>(jsonDataString);

                foreach (KeyValuePair<string, bool> pair in serializableDictionary)
                {
                    ExternalDependencyType externalDependencyType;
                    if (Enum.TryParse(pair.Key, out externalDependencyType))
                    {
                        if (Enum.IsDefined(typeof(ExternalDependencyType), externalDependencyType))
                        {
                            dictionary[externalDependencyType] = pair.Value;
                        }
                        else
                        {
                            HiveLogger.Log(String.Format("[ExternalDependencyDictionaryManager] LoadSavedLegacyData, {0} is not an underlying value of the ExternalDependencyType enumeration.", pair.Key));
                            continue;
                        }
                    }
                    else
                    {
                        HiveLogger.Log(String.Format("[ExternalDependencyDictionaryManager] LoadSavedLegacyData, {0} is not a member of the ExternalDependencyType enumeration.", pair.Key));
                        continue;
                    }
                }
            }
            else
            {
                HiveLogger.Log("[ExternalDependencyDictionaryManager] LoadSavedLegacyData, file not exist");
            }

            return dictionary;
        }

        private static ExternalDependencyDictionary LoadSavedXmlData(string filePath, SupportOSType osType, ExternalDependencyDictionary dictionary) {
            HiveLogger.Log(String.Format("[ExternalDependencyDictionaryManager] LoadSavedXmlData"));
            string osTypeName = "";
            if(osType == SupportOSType.Android) {
                osTypeName = XML_Attr_Android;
                HiveLogger.Log(String.Format("[ExternalDependencyDictionaryManager] LoadSavedXmlData, osType : Android"));
            } else {
                osTypeName = XML_Attr_iOS;
                HiveLogger.Log(String.Format("[ExternalDependencyDictionaryManager] LoadSavedXmlData, osType : iOS"));
            }

            if (File.Exists(filePath))
            {
                XmlDocument doc = new XmlDocument();
                doc.Load(ExternalDependencyConst.projSettingsXmlDataPath);

                XmlElement elHiveDependencies = doc[XML_Tag_HiveDependencies];

                foreach(XmlElement element in elHiveDependencies.ChildNodes)
                {
                    ExternalDependencyType externalDependencyType;
                    if (Enum.TryParse(element.Name, out externalDependencyType))
                    {
                        if (Enum.IsDefined(typeof(ExternalDependencyType), externalDependencyType))
                        {
                            bool include = false;
                            if(element.GetAttribute(osTypeName).Equals("true")) {
                                // HiveSDK v4 25.0.0 에서 include대신 Android 또는 iOS로 OSName으로 키가 변경되어 사용
                                include = true;
                            }
                            if(element.GetAttribute(XML_Attr_Include).Equals("true")) {
                                // HiveSDK v4 25.0.0 이전 include 키를 사용한 save file인 경우 값 획득 처리 (migration 대응)
                                include = true;
                            }

                            dictionary[externalDependencyType] = include;
                        }
                        else {
                            HiveLogger.Log(String.Format("[ExternalDependencyDictionaryManager] LoadSavedXmlData, {0} is not an underlying value of the ExternalDependencyType enumeration.", element.Name));
                            continue;
                        }
                    }
                    else
                    {
                        HiveLogger.Log(String.Format("[ExternalDependencyDictionaryManager] LoadSavedXmlData, {0} is not a member of the ExternalDependencyType enumeration.", element.Name));
                        continue;
                    }
                }
            }
            else
            {
                HiveLogger.Log("[ExternalDependencyDictionaryManager] LoadSavedXmlData, file not exist");
            }
            return dictionary;
        }

        // OS별 디펜던시 설정을 확인하여 /ProjectSettings/HiveDependencies.xml 파일을 생성합니다. (Hive 전용 세이브 파일)
        public static void SaveExternalDependencyDictionary(ExternalDependencyDictionary androidDependency, ExternalDependencyDictionary iosDependency)
        {
            HiveLogger.Log(String.Format("[ExternalDependencyDictionaryManager] SaveExternalDependencyDictionary"));

            // 각 OS 디펜던시에 대한 null check
            bool existAndroidSettings = false;
            bool existIOSSettings = false;
            if(androidDependency != null) {
                existAndroidSettings = true;
            }
            if(existIOSSettings != null) {
                existIOSSettings = true;
            }
            if(existAndroidSettings == false && existIOSSettings == false) {
                HiveLogger.Log(String.Format("[ExternalDependencyDictionaryManager] SaveExternalDependencyDictionary, android and ios dependencies are null"));
                return;
            }

            // Save Xml File
            XmlDocument doc = new XmlDocument();
            XmlElement elHiveDependencies = doc.CreateElement(XML_Tag_HiveDependencies);
            doc.AppendChild(elHiveDependencies);

            if(androidDependency != null)
            {
                foreach (var pair in androidDependency)
                {
                    // Android 디펜던시 속성값 확인
                    string elName = Enum.GetName(typeof(ExternalDependencyType), pair.Key);
                    string boolValue = "false";
                    if(pair.Value == true) {
                        boolValue = "true";
                    }

                    XmlElement existingElement = elHiveDependencies[elName];

                    if(existingElement != null)  {
                        existingElement.SetAttribute(XML_Attr_Android, boolValue);
                        elHiveDependencies.AppendChild(existingElement);
                    }
                    else {
                        XmlElement elProvider = doc.CreateElement(elName);
                        elProvider.SetAttribute(XML_Attr_Android, boolValue);
                        elHiveDependencies.AppendChild(elProvider);
                    }
                    
                }
            }
            if(iosDependency != null)
            {
                foreach (var pair in iosDependency)
                {
                    // iOS 디펜던시 속성값 확인
                    string elName = Enum.GetName(typeof(ExternalDependencyType), pair.Key);
                    string boolValue = "false";
                    if(pair.Value == true) {
                        boolValue = "true";
                    }

                    XmlElement existingElement = elHiveDependencies[elName];

                    if(existingElement != null)  {
                        existingElement.SetAttribute(XML_Attr_iOS, boolValue);
                        elHiveDependencies.AppendChild(existingElement);
                    }
                    else {
                        XmlElement elProvider = doc.CreateElement(elName);
                        elProvider.SetAttribute(XML_Attr_iOS, boolValue);
                        elHiveDependencies.AppendChild(elProvider);
                    }
                }
            }

            XmlElement elUpdatedInfo = doc.CreateElement(XML_Tag_UpdatedInfo);
            elUpdatedInfo.SetAttribute(XML_Attr_Version, Enum.GetName(typeof(SaveDataVersionType), SaveDataVersionType.Hive4250000));
            elHiveDependencies.AppendChild(elUpdatedInfo);

            doc.Save(ExternalDependencyConst.projSettingsXmlDataPath);

            // "Xml Example"
            //
            // <HiveDependencies>
            //     <Google Android="true" iOS="true"/>
            //     <GooglePlayGames Android="true" iOS="false"/>
            //     <Facebook Android="true" iOS="true"/>
            //     ...
            //     <MarketHiveStore Android="true" iOS="true"/>
            //     <UpdatedInfo version="Hive4250000" />
            // </HiveDependencies>

            // remove legacySaveData
            removeLegacySaveFiles();
        }

        private static void removeLegacySaveFiles() {
            ExternalDependencyUtil.deleteFile(ExternalDependencyConst.legacyJsonDataPath);         // 4.16.1 미만 버전 저장위치
            ExternalDependencyUtil.deleteFile(ExternalDependencyConst.jsonDataPath);               // 4.16.1 이상 23.0.0 미만 버전 저장위치
            ExternalDependencyUtil.deleteFile(ExternalDependencyConst.projSettingsJsonDataPath);   // 23.0.0 이상 23.4.0 미만 버전 저장위치
        }

        public static void Reset(SupportOSType osType, ref ExternalDependencyDictionary dictionary)
        {
            HiveLogger.Log(String.Format("[ExternalDependencyDictionaryManager] Reset"));

            dictionary.Clear();

            foreach (ExternalDependencyType i in Enum.GetValues(typeof(ExternalDependencyType)))
            {
                // 신규 Dependency 발생 시 유지 보수 사항을 줄이기 위해
                // reset 시 true 여야하는 것들만 조건에 표시
                if(i == ExternalDependencyType.HivePromotion
                    || i == ExternalDependencyType.GoogleInAppReview
                    || i == ExternalDependencyType.HiveDeviceManagement
                    || i == ExternalDependencyType.Hercules
                    || i == ExternalDependencyType.Recaptcha
                    || i == ExternalDependencyType.DataStore
                    || i == ExternalDependencyType.GoogleInAppUpdate
                    || i == ExternalDependencyType.AnalyticsConsentMode
                    || i == ExternalDependencyType.HiveMembership
                    || i == ExternalDependencyType.HiveAdultConfirm
                    || i == ExternalDependencyType.HiveIdentityVerification
                    || i == ExternalDependencyType.Google
                    || i == ExternalDependencyType.GooglePlayGames
                    || i == ExternalDependencyType.Facebook
                    || i == ExternalDependencyType.Apple
                    || i == ExternalDependencyType.AppleSignIn
                    || i == ExternalDependencyType.Line
                    || i == ExternalDependencyType.PushGoogleFcm
                    || i == ExternalDependencyType.MarketGoogle
                    || i == ExternalDependencyType.MarketApple)
                {
                    // default:false 설정 대상
                    dictionary[i] = true;
                    HiveLogger.Log(String.Format("[ExternalDependencyDictionaryManager] Reset, {0} default : true", i));
                }
                else
                {
                    // true 설정 외의 것들은 모두 기본 false
                    dictionary[i] = false;
                }
            }
        }

        // Jenkins에서 샘플 빌드 시 기본 디펜던시 파일을 생서하기 위한 reset 셋팅을 반환합니다. (Jenkins 샘플 빌드시에만 호출됩니다. 상용 패키지 로직에서 호출되지 않습니다.)
        public static void ResetForJenkinsMobileBuild(SupportOSType osType, ref ExternalDependencyDictionary dictionary)
        {
            HiveLogger.Log(String.Format("[ExternalDependencyDictionaryManager] ResetForJenkinsMobileBuild"));

            dictionary.Clear();

            foreach (ExternalDependencyType i in Enum.GetValues(typeof(ExternalDependencyType)))
            {
                if(i == ExternalDependencyType.Huawei
                    || i == ExternalDependencyType.PushAmazonAdm
                    || i == ExternalDependencyType.MarketAmazon
                    || i == ExternalDependencyType.MarketHuawei
                    || i == ExternalDependencyType.Xiaomi
                    || i == ExternalDependencyType.MarketXiaomi)
                {
                    // default:false 설정 대상
                    dictionary[i] = false;
                    HiveLogger.Log(String.Format("[ExternalDependencyDictionaryManager] ResetForJenkinsMobileBuild, {0} default : false", i));
                }
                else
                {
                    // "default값이 false 처리되야할 것 + 개별 조건" 외의 것들은 true 설정
                    dictionary[i] = true;
                }
            }
        }

        // 각 OS의 디펜던시를 따라 사용하지 않는 라이브러리 파일, 프레임워크 파일을 import 여부 처리합니다.
        public static void SetupIncludedExternalDependency(SupportOSType osType, ExternalDependencyDictionary dictionary)
        {
            if(osType == SupportOSType.Android) {
                SetupIncludedExternalDependencyForAndroid(dictionary);
                if(ExternalDependencyUtil.isSampleBuild()) {
                    SetupIncludeHiveSDKAarForAndroid(dictionary);
                }
            }
            else if(osType == SupportOSType.iOS) {
                SetupIncludedExternalDependencyForIOS(dictionary);
            }
        }

        private static void SetupIncludedExternalDependencyForAndroid(ExternalDependencyDictionary externalDependencyDictionary)
        {
            // Hive Unity default 및 package 경로내 Android 라이브러리 위치
            string[] libPathArr = new string[]{"Assets/Hive_SDK_v4/Plugins/Android/libs", "Assets/Hive_SDK_v4/Plugins/libs"};
            
            foreach(string libPath in libPathArr) {

                if (!Directory.Exists(libPath))
                {
                    Directory.CreateDirectory(libPath);
                }

                DirectoryInfo libDirInfo = new DirectoryInfo(libPath);
                FileInfo[] libFileInfoes = libDirInfo.GetFiles();
                if (libFileInfoes == null || libFileInfoes.Length == 0)
                {
                    HiveLogger.Log(libPath + "\n" + "FileInfo[] is null or empty");
                    continue;
                }
                else
                {
                    foreach (FileInfo f in libFileInfoes)
                    {
                        if (f.Extension.ToLower().Equals(".meta"))
                            continue;

                        PluginImporter plugin = PluginImporter.GetAtPath(libPath + "/" + f.Name) as PluginImporter;

                        // libPath 경로의 라이브러리를 디펜던시 여부에 따라 플러그인 임포트 처리 (외부 라이브러리 대상)
                        if (f.Name.Contains("open_sdk_"))
                        {
                            bool enable = externalDependencyDictionary[ExternalDependencyType.QQ];
                            plugin.SetCompatibleWithAnyPlatform(false);
                            plugin.SetCompatibleWithEditor(false);
                            plugin.SetCompatibleWithPlatform(BuildTarget.Android, enable);
                        }
                        else if (f.Name.Contains("mid-sdk-"))
                        {
                            bool enable = externalDependencyDictionary[ExternalDependencyType.QQ];
                            plugin.SetCompatibleWithAnyPlatform(false);
                            plugin.SetCompatibleWithEditor(false);
                            plugin.SetCompatibleWithPlatform(BuildTarget.Android, enable);
                        }
                        else if (f.Name.Contains("mta-sdk-"))
                        {
                            bool enable = externalDependencyDictionary[ExternalDependencyType.QQ] || externalDependencyDictionary[ExternalDependencyType.Wechat];
                            plugin.SetCompatibleWithAnyPlatform(false);
                            plugin.SetCompatibleWithEditor(false);
                            plugin.SetCompatibleWithPlatform(BuildTarget.Android, enable);
                        }
                        else if (f.Name.Contains("samsung-iap"))
                        {
                            bool enable = externalDependencyDictionary[ExternalDependencyType.MarketSamsung];
                            plugin.SetCompatibleWithAnyPlatform(false);
                            plugin.SetCompatibleWithEditor(false);
                            plugin.SetCompatibleWithPlatform(BuildTarget.Android, enable);
                        }
                        
                        try
                        {
                            plugin.SaveAndReimport();
                        }
                        catch (Exception ex)
                        {
                            HiveLogger.Log(String.Format("{0} is not allocated as PluginImporter. \n {1}", f.Name, ex.ToString()));
                        }   
                    }
                }

            }
        }

        // (for HiveSample) 샘플 빌드 시 HiveSDK Android AAR 포함 여부 제어
        private static void SetupIncludeHiveSDKAarForAndroid(ExternalDependencyDictionary externalDependencyDictionary) {
            string libPath = "Assets/Hive_SDK_v4/Plugins/Android/libs";
            
            if (!Directory.Exists(libPath))
            {
                HiveLogger.Log("SetupIncludeHiveSDKAarForAndroid, not exist libs path");
                return;
            }

            DirectoryInfo libDirInfo = new DirectoryInfo(libPath);
            FileInfo[] libFileInfoes = libDirInfo.GetFiles();
            if (libFileInfoes == null || libFileInfoes.Length == 0)
            {
                HiveLogger.Log("SetupIncludeHiveSDKAarForAndroid, libs path is empty");
                return;
            }

            foreach (FileInfo f in libFileInfoes)
            {
                if (f.Extension.ToLower().Equals(".meta"))
                    continue;

                PluginImporter plugin = PluginImporter.GetAtPath(libPath + "/" + f.Name) as PluginImporter;
                bool enable = true;
                bool enableChanged = false;

                // libPath 경로의 라이브러리를 디펜던시 여부에 따라 플러그인 임포트 처리 (Hive 라이브러리 대상)
                // (1) Analytics Consent Mode
                if (f.Name.Contains("hive-analytics-consent-mode"))
                {
                    enable = externalDependencyDictionary[ExternalDependencyType.AnalyticsConsentMode];
                    enableChanged = true;
                }
                // (2) Adjust
                else if (f.Name.Contains("hive-analytics-provider-adjust"))
                {
                    enable = externalDependencyDictionary[ExternalDependencyType.Adjust];
                    enableChanged = true;
                }
                // (3) Airbridge
                else if (f.Name.Contains("hive-analytics-provider-airbridge"))
                {
                    enable = externalDependencyDictionary[ExternalDependencyType.Airbridge];
                    enableChanged = true;
                }
                // (4) Appsflyer
                else if (f.Name.Contains("hive-analytics-provider-appsflyer"))
                {
                    enable = externalDependencyDictionary[ExternalDependencyType.AppsFlyer];
                    enableChanged = true;
                }
                // (5) Firebase
                else if (f.Name.Contains("hive-analytics-provider-firebase"))
                {
                    enable = externalDependencyDictionary[ExternalDependencyType.Firebase];
                    enableChanged = true;
                }
                // (6) Singular
                else if (f.Name.Contains("hive-analytics-provider-singular"))
                {
                    enable = externalDependencyDictionary[ExternalDependencyType.Singular];
                    enableChanged = true;
                }
                // (7) Device Management
                else if (f.Name.Contains("hive-authv4-device-management"))
                {
                    enable = externalDependencyDictionary[ExternalDependencyType.HiveDeviceManagement];
                    enableChanged = true;
                }
                // (8) Google Inapp Update
                else if (f.Name.Contains("hive-authv4-google-inappupdate"))
                {
                    enable = externalDependencyDictionary[ExternalDependencyType.GoogleInAppUpdate];
                    enableChanged = true;
                }
                // (9) Recaptcha
                else if (f.Name.Contains("hive-authv4-google-recaptcha"))
                {
                    enable = externalDependencyDictionary[ExternalDependencyType.Recaptcha];
                    enableChanged = true;
                }
                // (10) Apple Signin
                else if (f.Name.Contains("hive-authv4-provider-apple-signin"))
                {
                    enable = externalDependencyDictionary[ExternalDependencyType.AppleSignIn];
                    enableChanged = true;
                }
                // (11) Facebook
                else if (f.Name.Contains("hive-authv4-provider-facebook"))
                {
                    enable = externalDependencyDictionary[ExternalDependencyType.Facebook];
                    enableChanged = true;
                }
                // (12) Google Play Games
                else if (f.Name.Contains("hive-authv4-provider-google-playgames"))
                {
                    enable = externalDependencyDictionary[ExternalDependencyType.GooglePlayGames];
                    enableChanged = true;
                }
                // (13) Google SignIn
                else if (f.Name.Contains("hive-authv4-provider-google-signin"))
                {
                    enable = externalDependencyDictionary[ExternalDependencyType.Google];
                    enableChanged = true;
                }
                // (14) Hive Membership
                else if (f.Name.Contains("hive-authv4-provider-hive-membership"))
                {
                    enable = externalDependencyDictionary[ExternalDependencyType.HiveMembership];
                    enableChanged = true;
                }
                // (15) Huawei
                else if (f.Name.Contains("hive-authv4-provider-huawei"))
                {
                    enable = externalDependencyDictionary[ExternalDependencyType.Huawei];
                    enableChanged = true;
                }
                // (16) Line
                else if (f.Name.Contains("hive-authv4-provider-line"))
                {
                    enable = externalDependencyDictionary[ExternalDependencyType.Line];
                    enableChanged = true;
                }
                // (17) QQ
                else if (f.Name.Contains("hive-authv4-provider-qq"))
                {
                    enable = externalDependencyDictionary[ExternalDependencyType.QQ];
                    enableChanged = true;
                }
                // (18) VK
                else if (f.Name.Contains("hive-authv4-provider-vk"))
                {
                    enable = externalDependencyDictionary[ExternalDependencyType.VK];
                    enableChanged = true;
                }
                // (19) Wechat
                else if (f.Name.Contains("hive-authv4-provider-wechat"))
                {
                    enable = externalDependencyDictionary[ExternalDependencyType.Wechat];
                    enableChanged = true;
                }
                // (20) Weverse
                else if (f.Name.Contains("hive-authv4-provider-weverse"))
                {
                    enable = externalDependencyDictionary[ExternalDependencyType.Weverse];
                    enableChanged = true;
                }
                // (21) Real Name Verification
                else if (f.Name.Contains("hive-authv4-real-name-verification"))
                {
                    enable = externalDependencyDictionary[ExternalDependencyType.HiveRealNameVerification];
                    enableChanged = true;
                }
                // (22) Datastore
                else if (f.Name.Contains("hive-datastore"))
                {
                    enable = externalDependencyDictionary[ExternalDependencyType.DataStore];
                    enableChanged = true;
                }
                // (23) Hercules
                else if (f.Name.Contains("hive-hercules"))
                {
                    enable = externalDependencyDictionary[ExternalDependencyType.Hercules];
                    enableChanged = true;
                }
                // (24) Amazon Market
                else if (f.Name.Contains("hive-iapv4-market-amazon"))
                {
                    enable = externalDependencyDictionary[ExternalDependencyType.MarketAmazon];
                    enableChanged = true;
                }
                // (25) Google Market
                else if (f.Name.Contains("hive-iapv4-market-google"))
                {
                    enable = externalDependencyDictionary[ExternalDependencyType.MarketGoogle];
                    enableChanged = true;
                }
                // (26) Hivestore
                else if (f.Name.Contains("hive-iapv4-market-hivestore"))
                {
                    enable = externalDependencyDictionary[ExternalDependencyType.MarketHiveStore];
                    enableChanged = true;
                }
                // (27) Huawei Market
                else if (f.Name.Contains("hive-iapv4-market-huawei"))
                {
                    enable = externalDependencyDictionary[ExternalDependencyType.MarketHuawei];
                    enableChanged = true;
                }
                // (28) Lebi Market
                else if (f.Name.Contains("hive-iapv4-market-lebi"))
                {
                    enable = externalDependencyDictionary[ExternalDependencyType.MarketLebi];
                    enableChanged = true;
                }
                // (29) Onestore Market
                else if (f.Name.Contains("hive-iapv4-market-onestore"))
                {
                    enable = externalDependencyDictionary[ExternalDependencyType.MarketOneStore];
                    enableChanged = true;
                }
                // (30) Samsung Market
                else if (f.Name.Contains("hive-iapv4-market-samsung"))
                {
                    enable = externalDependencyDictionary[ExternalDependencyType.MarketSamsung];
                    enableChanged = true;
                }
                // (31) Promotion
                else if (f.Name.Contains("hive-promotion"))
                {
                    enable = externalDependencyDictionary[ExternalDependencyType.HivePromotion];
                    enableChanged = true;
                }
                // (32) Google Inapp Review
                else if (f.Name.Contains("hive-promotion-google-inappreview"))
                {
                    enable = externalDependencyDictionary[ExternalDependencyType.GoogleInAppReview];
                    enableChanged = true;
                }
                // (33) Amazon ADM
                else if (f.Name.Contains("hive-push-amazon-adm"))
                {
                    enable = externalDependencyDictionary[ExternalDependencyType.PushAmazonAdm];
                    enableChanged = true;
                }
                // (34) Google FCM
                else if (f.Name.Contains("hive-push-google-fcm"))
                {
                    enable = externalDependencyDictionary[ExternalDependencyType.PushGoogleFcm];
                    enableChanged = true;
                }
                // (35) X
                else if (f.Name.Contains("hive-authv4-provider-x"))
                {
                    enable = externalDependencyDictionary[ExternalDependencyType.X];
                    enableChanged = true;
                }
                // (36) MatchMaking
                else if (f.Name.Contains("hive-matchmaking"))
                {
                    enable = externalDependencyDictionary[ExternalDependencyType.MatchMaking];
                    enableChanged = true;
                }
                // (37) Steam
                else if (f.Name.Contains("hive-authv4-provider-steam"))
                {
                    enable = externalDependencyDictionary[ExternalDependencyType.Steam];
                    enableChanged = true;
                }
                // (38) Telegram
                else if (f.Name.Contains("hive-authv4-provider-telegram"))
                {
                    enable = externalDependencyDictionary[ExternalDependencyType.Telegram];
                    enableChanged = true;
                }
                // (39) Chat
                else if (f.Name.Contains("hive-chat"))
                {
                    enable = externalDependencyDictionary[ExternalDependencyType.Chat];
                    enableChanged = true;
                }
                // (40) Adult Confirm
                else if (f.Name.Contains("hive-authv4-adult-confirm"))
                {
                    enable = externalDependencyDictionary[ExternalDependencyType.HiveAdultConfirm];
                    enableChanged = true;
                }
                // (41) Identity Verification
                else if (f.Name.Contains("hive-authv4-identity-verification"))
                {
                    enable = externalDependencyDictionary[ExternalDependencyType.HiveIdentityVerification];
                    enableChanged = true;
                }
                // (42) Xiaomi-Oauth(China)
                else if (f.Name.Contains("hive-authv4-provider-xiaomi-oauth"))
                {
                    enable = externalDependencyDictionary[ExternalDependencyType.Xiaomi];
                    enableChanged = true;
                }
                // (43) Xiaomi-Billing(China)
                else if (f.Name.Contains("hive-iapv4-market-xiaomi-billing"))
                {
                    enable = externalDependencyDictionary[ExternalDependencyType.MarketXiaomi];
                    enableChanged = true;   
                }
                // (44) Hive Age Range Google
                else if (f.Name.Contains("hive-agerange-google-agesignals"))
                {
                    enable = externalDependencyDictionary[ExternalDependencyType.HiveAgeRangeGoogle];
                    enableChanged = true;   
                }
                // Repayment, Google-Base는 제어 목록에서 제외

                if (enableChanged)
                {
                    plugin.SetCompatibleWithAnyPlatform(false);
                    plugin.SetCompatibleWithEditor(false);
                    plugin.SetCompatibleWithPlatform(BuildTarget.Android, enable);

                    try
                    {
                        plugin.SaveAndReimport();
                    }
                    catch (Exception ex)
                    {
                        HiveLogger.Log(String.Format("{0} is not allocated as PluginImporter. \n {1}", f.Name, ex.ToString()));
                    }
                }
            }
        }

        private static void SetupIncludedExternalDependencyForIOS(ExternalDependencyDictionary externalDependencyDictionary) {
            var frameworkPath = "Assets/Hive_SDK_v4/Plugins/iOS/framework";

            if (!Directory.Exists(frameworkPath))
            {
                Directory.CreateDirectory(frameworkPath);
            }

            DirectoryInfo frameworkDirInfo = new DirectoryInfo(frameworkPath);
            DirectoryInfo[] frameworkDirInfoes = frameworkDirInfo.GetDirectories();
            if (frameworkDirInfoes == null || frameworkDirInfoes.Length == 0)
            {
                HiveLogger.Log(frameworkPath + "\n" + "DirectoryInfo[] is null or empty");
                return;
            }

            foreach (DirectoryInfo d in frameworkDirInfoes)
            {
                PluginImporter plugin = PluginImporter.GetAtPath(frameworkPath + "/" + d.Name) as PluginImporter;

                if (d.Name.Equals("WXApi.framework"))
                {
                    bool enable = externalDependencyDictionary[ExternalDependencyType.Wechat];
                    plugin.SetCompatibleWithAnyPlatform(false);
                    plugin.SetCompatibleWithEditor(false);
                    plugin.SetCompatibleWithPlatform(BuildTarget.iOS, enable);

                }
                else if (d.Name.Equals("TencentOpenAPI.framework"))
                {
                    bool enable = externalDependencyDictionary[ExternalDependencyType.QQ];
                    plugin.SetCompatibleWithAnyPlatform(false);
                    plugin.SetCompatibleWithEditor(false);
                    plugin.SetCompatibleWithPlatform(BuildTarget.iOS, enable);
                }
                else if (d.Name.Equals("ProviderAdapter.framework"))
                {
                    plugin.SetCompatibleWithAnyPlatform(false);
                    plugin.SetCompatibleWithEditor(false);
                    plugin.SetCompatibleWithPlatform(BuildTarget.iOS, true);
                }

                /*
                    HIVE 제공 framework
                */
                else if (d.Name.Contains("ProviderWechat"))
                {
                    bool enable = externalDependencyDictionary[ExternalDependencyType.Wechat];
                    plugin.SetCompatibleWithAnyPlatform(false);
                    plugin.SetCompatibleWithEditor(false);
                    plugin.SetCompatibleWithPlatform(BuildTarget.iOS, enable);
                }
                else if (d.Name.Contains("ProviderVK"))
                {
                    bool enable = externalDependencyDictionary[ExternalDependencyType.VK];
                    plugin.SetCompatibleWithAnyPlatform(false);
                    plugin.SetCompatibleWithEditor(false);
                    plugin.SetCompatibleWithPlatform(BuildTarget.iOS, enable);
                }
                else if (d.Name.Contains("ProviderSingular"))
                {
                    bool enable = externalDependencyDictionary[ExternalDependencyType.Singular];
                    plugin.SetCompatibleWithAnyPlatform(false);
                    plugin.SetCompatibleWithEditor(false);
                    plugin.SetCompatibleWithPlatform(BuildTarget.iOS, enable);
                }
                else if (d.Name.Contains("ProviderQQ"))
                {
                    bool enable = externalDependencyDictionary[ExternalDependencyType.QQ];
                    plugin.SetCompatibleWithAnyPlatform(false);
                    plugin.SetCompatibleWithEditor(false);
                    plugin.SetCompatibleWithPlatform(BuildTarget.iOS, enable);
                }
                else if (d.Name.Contains("ProviderLine"))
                {
                    bool enable = externalDependencyDictionary[ExternalDependencyType.Line];
                    plugin.SetCompatibleWithAnyPlatform(false);
                    plugin.SetCompatibleWithEditor(false);
                    plugin.SetCompatibleWithPlatform(BuildTarget.iOS, enable);
                }
                else if (d.Name.Contains("ProviderWeverse"))
                {
                    bool enable = externalDependencyDictionary[ExternalDependencyType.Weverse];
                    plugin.SetCompatibleWithAnyPlatform(false);
                    plugin.SetCompatibleWithEditor(false);
                    plugin.SetCompatibleWithPlatform(BuildTarget.iOS, enable);
                }
                else if (d.Name.Contains("ProviderSteam"))
                {
                    bool enable = externalDependencyDictionary[ExternalDependencyType.Steam];
                    plugin.SetCompatibleWithAnyPlatform(false);
                    plugin.SetCompatibleWithEditor(false);
                    plugin.SetCompatibleWithPlatform(BuildTarget.iOS, enable);
                }
                else if (d.Name.Contains("ProviderX"))
                {
                    bool enable = externalDependencyDictionary[ExternalDependencyType.X];
                    plugin.SetCompatibleWithAnyPlatform(false);
                    plugin.SetCompatibleWithEditor(false);
                    plugin.SetCompatibleWithPlatform(BuildTarget.iOS, enable);
                }
                else if (d.Name.Contains("ProviderTelegram"))
                {
                    bool enable = externalDependencyDictionary[ExternalDependencyType.Telegram];
                    plugin.SetCompatibleWithAnyPlatform(false);
                    plugin.SetCompatibleWithEditor(false);
                    plugin.SetCompatibleWithPlatform(BuildTarget.iOS, enable);
                }
                else if (d.Name.Contains("ProviderAppsFlyer"))
                {
                    bool enable = externalDependencyDictionary[ExternalDependencyType.AppsFlyer];
                    plugin.SetCompatibleWithAnyPlatform(false);
                    plugin.SetCompatibleWithEditor(false);
                    plugin.SetCompatibleWithPlatform(BuildTarget.iOS, enable);
                }
                else if (d.Name.Contains("ProviderAdjust"))
                {
                    bool enable = externalDependencyDictionary[ExternalDependencyType.Adjust];
                    plugin.SetCompatibleWithAnyPlatform(false);
                    plugin.SetCompatibleWithEditor(false);
                    plugin.SetCompatibleWithPlatform(BuildTarget.iOS, enable);
                }
                else if (d.Name.Contains("ProviderAirbridge"))
                {
                    bool enable = externalDependencyDictionary[ExternalDependencyType.Airbridge];
                    plugin.SetCompatibleWithAnyPlatform(false);
                    plugin.SetCompatibleWithEditor(false);
                    plugin.SetCompatibleWithPlatform(BuildTarget.iOS, enable);
                }
                else if (d.Name.Contains("ProviderFirebase"))
                {
                    bool enable = externalDependencyDictionary[ExternalDependencyType.Firebase];
                    plugin.SetCompatibleWithAnyPlatform(false);
                    plugin.SetCompatibleWithEditor(false);
                    plugin.SetCompatibleWithPlatform(BuildTarget.iOS, enable);
                }
                else if (d.Name.Contains("HiveRecaptcha"))
                {
                    bool enable = externalDependencyDictionary[ExternalDependencyType.Recaptcha];
                    plugin.SetCompatibleWithAnyPlatform(false);
                    plugin.SetCompatibleWithEditor(false);
                    plugin.SetCompatibleWithPlatform(BuildTarget.iOS, enable);
                }
                else if (d.Name.Contains("Hercules"))
                {
                    bool enable = externalDependencyDictionary[ExternalDependencyType.Hercules];
                    plugin.SetCompatibleWithAnyPlatform(false);
                    plugin.SetCompatibleWithEditor(false);
                    plugin.SetCompatibleWithPlatform(BuildTarget.iOS, enable);
                }
                else if (d.Name.Contains("ProviderApple"))
                {
                    bool enable = externalDependencyDictionary[ExternalDependencyType.Apple];
                    plugin.SetCompatibleWithAnyPlatform(false);
                    plugin.SetCompatibleWithEditor(false);
                    plugin.SetCompatibleWithPlatform(BuildTarget.iOS, enable);
                }
                else if (d.Name.Contains("ProviderHive"))
                {
                    bool enable = externalDependencyDictionary[ExternalDependencyType.HiveMembership];
                    plugin.SetCompatibleWithAnyPlatform(false);
                    plugin.SetCompatibleWithEditor(false);
                    plugin.SetCompatibleWithPlatform(BuildTarget.iOS, enable);
                }
                else if (d.Name.Contains("HiveChat"))
                {
                    bool enable = externalDependencyDictionary[ExternalDependencyType.Chat];
                    plugin.SetCompatibleWithAnyPlatform(false);
                    plugin.SetCompatibleWithEditor(false);
                    plugin.SetCompatibleWithPlatform(BuildTarget.iOS, enable);
                }

                try
                {
                    plugin.SaveAndReimport();
                }
                catch (Exception ex)
                {
                    HiveLogger.Log(String.Format("{0} is not allocated as PluginImporter. \n {1}", d.Name, ex.ToString()));
                }
            }
        }

        // OS별 디펜던시 설정을 확인하여 /Editor/HiveSDKSettingsDependencies.xml 파일을 생성합니다. (for EDM4U)
        public static void createHiveSDKSettingsDependenciesXmlFile(Dictionary<SupportOSType, ExternalDependencyDictionary> osDependenciesDict) { 

            // (1) xml 구성할 string 생성
            string xmlText = "";

            xmlText += "<dependencies>\n";

            foreach(KeyValuePair<SupportOSType, ExternalDependencyDictionary> pair in osDependenciesDict) {
                if(pair.Key == SupportOSType.Android) {
                    if(File.Exists(ExternalDependencyConst.editorPath + "/ExternalDependency/Android/AndroidDependencyInfo.cs")) {
                        object[] invokeParams = new object[] {
                            pair.Value
                        };
                        string tempValue = Utility.InvokeStringMethod("AndroidDependencyInfo", "getAndroidPackagesData", invokeParams);
                        if(tempValue != "") {
                            xmlText += (tempValue + "\n");
                        }
                    }
                }
                else if(pair.Key == SupportOSType.iOS) {
                    if(File.Exists(ExternalDependencyConst.editorPath + "/ExternalDependency/iOS/iOSDependencyInfo.cs")) {
                        object[] invokeParams = new object[] {
                            pair.Value
                        };
                        string tempValue = Utility.InvokeStringMethod("iOSDependencyInfo", "getiOSPodsData", invokeParams);
                        if(tempValue != "") {
                            xmlText += (tempValue + "\n");
                        }
                    }
                }
            }

            xmlText += "</dependencies>\n";

            // (2) 이전 파일이 있다면 제거
            ExternalDependencyUtil.deleteFile(ExternalDependencyConst.hiveDependenciesXmlPath);

            // (3) string을 파일로 저장
            File.WriteAllText(ExternalDependencyConst.hiveDependenciesXmlPath, xmlText);

            // #GCPSDK4-2372 (4 - 임시 대응)
            rewriteiOSVersion();
        }

        // #GCPSDK4-2372, HiveSDKSettingsDependencies.xml 파일의 iOS SDK 버전이 "" 빈 값인 경우 현재 iOS json 버전에 있는 값으로 대체합니다.
        // 26.1.0에서 확인된 이슈 수정사항으로 다음 SDK 버전에서 rewriteiOSVersion() 메서드는 폐기하고 iOSDependencyInfo.cs를 수정합니다.
        // 폐기 예정 코드 : rewriteiOSVersion(), TempVersionFileInfo
        private static void rewriteiOSVersion() {
            if(!File.Exists(ExternalDependencyConst.hiveDependenciesXmlPath)) {
                return;
            }

            string iOSSdkVersion = "";
            if(!File.Exists(ExternalDependencyConst.hiveiOSVersionJsonPath)) {
                return;
            }
            else {
                try
                {
                    var json = System.IO.File.ReadAllText(ExternalDependencyConst.hiveiOSVersionJsonPath);
                    var versionFileInfo = JsonUtility.FromJson<TempVersionFileInfo>(json);
                    iOSSdkVersion = versionFileInfo.version;
                }
                catch (Exception e)
                {
                    return;
                }
            }

            var lines = File.ReadAllLines(ExternalDependencyConst.hiveDependenciesXmlPath, Encoding.UTF8);
            bool modified = false;

            for (int i = 0; i < lines.Length; i++)
            {
                string line = lines[i];

                if (line.Contains("<iosPod") && line.Contains("version=\"\""))
                {
                    lines[i] = line.Replace("version=\"\"", $"version=\"{iOSSdkVersion}\"");
                    modified = true;
                }
            }

            if (modified) {
                File.WriteAllLines(ExternalDependencyConst.hiveDependenciesXmlPath, lines, Encoding.UTF8);
            }
        }
        [System.Serializable]
        public class TempVersionFileInfo
        {
            public string type;
            public string os;
            public string version;
        }

        public static void initTempDependencies()
        {
            tempEditorAndroidDepend = new ExternalDependencyDictionary();
            tempEditoriOSDepend = new ExternalDependencyDictionary();
        }

        public static void setTempDependencies(ExternalDependencyDictionary dictionary, SupportOSType osType)
        {
            if(osType == SupportOSType.Android)
            {
                tempEditorAndroidDepend = dictionary;
            }
            else
            {
                tempEditoriOSDepend = dictionary;
            }
        }

        public static ExternalDependencyDictionary getTempDependencies(SupportOSType osType)
        {
            if(osType == SupportOSType.Android)
            {
                return tempEditorAndroidDepend;
            }
            else
            {
                return tempEditoriOSDepend;
            }
        }

        public static void ResolveEDM4U()
        {
#if UNITY_ANDROID
            string mainTemplatePath = Path.Combine(Application.dataPath, "Plugins/Android/mainTemplate.gradle");

            // platfrom Android 설정된 상태에서 mainTemplate.gradle이 존재하지 않은채 Resolve 수행시, 프리징
            // - mainTemplate.gradle 파일이 있어도 프리징 발생할 경우 mainTemplate을 삭제하고
            //   Hive Config 설정 Editor의 Regenrate~ 기능을 통해 재생성 후 수행해볼 것 (mainTemplate.gradle 충돌)
            if (File.Exists(mainTemplatePath))
            {
                GooglePlayServices.PlayServicesResolver.Resolve(null, true, null);
                GooglePlayServices.PlayServicesResolver.ResolveSync(true);
            }
            else
            {
                HiveLogger.Log("Failed EDM4U Resolve. Please check if the file(Plugins/Android/mainTemplate.gradle) exist.");
            }
#endif
        }

        public enum LegacyExternalDependencyType
        {
            // IDP
            Google,
            Facebook,
            Line,
            VK,
            QQ,
            Wechat,

            // Analytics
            Adjust,
            Singular,
            AppsFlyer,
            Firebase,

            // Push
            Fcm,

            // Etc
            Recaptcha,
            AndroidEmoji,
        }

    }  

}   