#if UNITY_IOS
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;

using InMobiAds.Api;
using InMobiAds.Common;
using InMobiAds.Api.UnifiedId;

namespace  InMobiAds.Platforms.iOS
{
    internal class InMobiUnifiedIdClient: IInMobiUnifiedIdClient, IDisposable
    {

        public const String IM_PHONE_MD5 = "phoneNumberMD5";
        public const String IM_PHONE_SHA1 = "phoneNumberSHA1";
        public const String IM_PHONE_SHA256 = "phoneNumberSHA256";
        public const String IM_EMAIlID_MD5 = "emailIdMD5";
        public const String IM_EMAIlID_SHA1 = "emailIdSHA1";
        public const String IM_EMAIlID_SHA256 = "emailIdSHA256";
        public const String IM_EXTRA = "extras";

        private IntPtr UnifiedIdClientPtr;
        private IntPtr unifiedIdServicePtr;

        #region UnifiedId callback types

		internal delegate void InMobiOnFetchCompleted(IntPtr unifiedIdClient, string response, string error);

		#endregion

        public event EventHandler<OnFetchCompletedEventArgs> OnFetchCompleted;

		private IntPtr UnifiedIdServicePtr
		{
			get
			{
				return this.unifiedIdServicePtr;
			}

			set
			{
				InMobiBinding.InMobiRelease(this.unifiedIdServicePtr);
				this.unifiedIdServicePtr = value;
			}
		}
        public InMobiUnifiedIdClient ()
        { 
            this.UnifiedIdClientPtr = (IntPtr)GCHandle.Alloc(this);
            this.UnifiedIdServicePtr = InMobiBinding.InMobiCreateUnifiedIdService(this.UnifiedIdClientPtr);
        }

        public void Push (InMobiUserDataModel inMobiUserDataModel)
		{
			InMobiBinding.Push(this.UnifiedIdServicePtr, getUserDataModelJsonString(inMobiUserDataModel));
	    }

        public void FetchUnifiedIds ()
		{
            InMobiBinding.SetUnifiedIdCallbacks (this.UnifiedIdServicePtr, onFetchCompleted);

            InMobiBinding.FetchUnifiedIds(this.UnifiedIdServicePtr);
	    }

        public void Reset ()
		{
			InMobiBinding.Reset(this.UnifiedIdServicePtr);
	    }

		public void Dispose()
		{
			((GCHandle)this.UnifiedIdClientPtr).Free();
		}

        public void EnableDebugMode (bool debugMode) {
            InMobiBinding.EnableDebugMode(this.UnifiedIdServicePtr, debugMode);
        }

		~InMobiUnifiedIdClient()
		{
			this.Dispose();
		}

        #region UnifiedId callback methods

        [MonoPInvokeCallbackAttribute(typeof(InMobiOnFetchCompleted))]
		private static void onFetchCompleted(IntPtr unifiedIdClient, string response, string error){
			InMobiUnifiedIdClient client = IntPtrToUnifiedIdClient (unifiedIdClient);
			OnFetchCompletedEventArgs args = new OnFetchCompletedEventArgs () {
				unifiedIds = response,
                error = error
			};
			client.OnFetchCompleted (client, args);
		}

		private static InMobiUnifiedIdClient IntPtrToUnifiedIdClient(IntPtr unifiedIdClient)
		{
			GCHandle handle = (GCHandle)unifiedIdClient;
			return handle.Target as InMobiUnifiedIdClient;
		}

        #endregion


        private string getUserDataModelJsonString(InMobiUserDataModel inMobiUserDataModel) {

            Dictionary<string, string> dataModel = new Dictionary<string, string>();

            if(inMobiUserDataModel.PhoneNumber != null)
            {
                if(inMobiUserDataModel.PhoneNumber.Md5 != null)
                    dataModel.Add(IM_PHONE_MD5, inMobiUserDataModel.PhoneNumber.Md5);
                if(inMobiUserDataModel.PhoneNumber.Sha1 != null)
                    dataModel.Add(IM_PHONE_SHA1, inMobiUserDataModel.PhoneNumber.Sha1);
                if(inMobiUserDataModel.PhoneNumber.Sha256 != null)
                    dataModel.Add(IM_PHONE_SHA256, inMobiUserDataModel.PhoneNumber.Sha256);
            }
            
            
            if(inMobiUserDataModel.EmailId != null) 
            {
                if(inMobiUserDataModel.EmailId.Md5 != null)
                    dataModel.Add(IM_EMAIlID_MD5, inMobiUserDataModel.EmailId.Md5);
                if(inMobiUserDataModel.EmailId.Sha1 != null)
                    dataModel.Add(IM_EMAIlID_SHA1, inMobiUserDataModel.EmailId.Sha1);
                if(inMobiUserDataModel.EmailId.Sha256 != null)
                    dataModel.Add(IM_EMAIlID_SHA256, inMobiUserDataModel.EmailId.Sha256);
            }
            
                

            return DictionaryToString(dataModel);
            
        }

        private string DictionaryToString(Dictionary < string, string > dictionary) {  
            string dictionaryString = "{";  
            foreach(KeyValuePair < string, string > kvp in dictionary) {  

                string token = "";
                token = "\""+ kvp.Value + "\"";
                

                dictionaryString += "\"" + kvp.Key + "\"" + " : " + token + ", ";  
            }  
            return dictionaryString.TrimEnd(',', ' ') + "}";  
        }

    }    
}

#endif