// DO NOT EDIT! This is an autogenerated file. All changes will be
// overwritten!

//	Copyright (c) 2023 Vidyo, Inc. All rights reserved.


using System;
using System.Runtime.InteropServices;
using System.Collections.Generic;

namespace VidyoClient
{
	/// <summary>
	/// 
	/// </summary>
	public class Application: IDisposable {
		private bool disposed = false; 
#if __IOS__
		const string importLib = "__Internal";
#else
		const string importLib = "libVidyoClient";
#endif
		private IntPtr objPtr; // opaque VidyoApplication reference.
		private GCHandle objHandle; // weak VidyoApplication reference.
		public IntPtr GetObjectPtr() {
			return objPtr;
		}
		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		private static extern IntPtr VidyoApplicationConstructNative(IntPtr endpoint);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		private static extern IntPtr VidyoApplicationConstructCopyNative(IntPtr other);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		private static extern void VidyoApplicationDestructNative(IntPtr obj);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoApplicationRegisterUpdaterEventListenerNative(IntPtr app, DownloadCompletedCallback onDownloadCompleted, DownloadFailedCallback onDownloadFailed);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		private static extern void VidyoApplicationSetWebProxyCredentialsNative(IntPtr app, IntPtr webProxyUserName, IntPtr webProxyPassword);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoApplicationStartUpdateServiceNative(IntPtr app, IntPtr currentVersion, IntPtr workingDirectory, IntPtr server, IntPtr caFilePath, IntPtr webProxyUsername, IntPtr webProxyPassword);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		private static extern void VidyoApplicationStopUpdateServiceNative(IntPtr app);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		public static extern IntPtr VidyoApplicationGetUserDataNative(IntPtr obj);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		public static extern void VidyoApplicationSetUserDataNative(IntPtr obj, IntPtr userData);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		private delegate void DownloadCompletedCallback(IntPtr app, IntPtr version, IntPtr downloadedFile);
		private DownloadCompletedCallback _mDownloadCompletedCallback = DownloadCompletedCallbackDelegate;
		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		private static extern IntPtr VidyoApplicationDownloadCompletedCallbackGetversionCStr(IntPtr version);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		private static extern IntPtr VidyoApplicationDownloadCompletedCallbackGetdownloadedFileCStr(IntPtr downloadedFile);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		private delegate void DownloadFailedCallback(IntPtr app, ApplicationDownloadFailedReason reason);
		private DownloadFailedCallback _mDownloadFailedCallback = DownloadFailedCallbackDelegate;
		/// <summary>
		/// The reason of failed update check
		/// </summary>
		public enum ApplicationDownloadFailedReason {
			/// <summary>Check for update failed because of webproxy authentication failure</summary>
			ApplicationDOWNLOADFAILEDREASON_WebProxyAuthenticationRequired,
			/// <summary>Check for update failed because of misc error</summary>
			ApplicationDOWNLOADFAILEDREASON_MiscError
		}
		public interface IRegisterUpdaterEventListener{

			void DownloadCompletedCallback(String version, String downloadedFile);
			void DownloadFailedCallback(ApplicationDownloadFailedReason reason);
		}
		private IRegisterUpdaterEventListener _mIRegisterUpdaterEventListener;
		/// <summary>
		/// 
		/// </summary>
		/// <param name="application"></param>
		/// <param name="endpoint"></param>
		/// <param name="alloc"></param>
		public Application(Endpoint endpoint) {

			objPtr = VidyoApplicationConstructNative((endpoint != null) ? endpoint.GetObjectPtr():IntPtr.Zero);
			objHandle = GCHandle.Alloc(this, GCHandleType.Weak);
			VidyoApplicationSetUserDataNative(objPtr, GCHandle.ToIntPtr(objHandle));
		}
		public Application(IntPtr other){
			objPtr = VidyoApplicationConstructCopyNative(other);
			objHandle = GCHandle.Alloc(this, GCHandleType.Weak);
			VidyoApplicationSetUserDataNative(objPtr, GCHandle.ToIntPtr(objHandle));
		}
		~Application(){
			Dispose(false);
		}
		public void Dispose(){
			Dispose(true);
			GC.SuppressFinalize(this);
		}

		public void Dispose(bool disposing){
			if(disposed) return;

			disposed = true;
			if(objPtr != IntPtr.Zero) {
				VidyoApplicationSetUserDataNative(objPtr, IntPtr.Zero);
				VidyoApplicationDestructNative(objPtr);
				objPtr = IntPtr.Zero;
			}

			if(objHandle.IsAllocated) objHandle.Free();
		}

		/// <summary>
		/// Registers to get notified about software updater events.
		/// </summary>
		/// <param name="app">The VidyoApplication object.</param>
		/// <param name="onDownloadCompleted"></param>
		/// <param name="onDownloadFailed"></param>
		public Boolean RegisterUpdaterEventListener(IRegisterUpdaterEventListener _iIRegisterUpdaterEventListener) {
			if (objPtr == IntPtr.Zero) { return default; }
			_mIRegisterUpdaterEventListener = _iIRegisterUpdaterEventListener;

			Boolean ret = VidyoApplicationRegisterUpdaterEventListenerNative(objPtr, _mDownloadCompletedCallback, _mDownloadFailedCallback);

			return ret;
		}
		/// <summary>
		/// 
		/// </summary>
		/// <param name="app">The application object.</param>
		/// <param name="webProxyUserName"></param>
		/// <param name="webProxyPassword"></param>
		public void SetWebProxyCredentials(String webProxyUserName, String webProxyPassword) {
			if (objPtr == IntPtr.Zero) { return; }

			IntPtr nWebProxyUserName = MarshalPtrToUtf8.GetInstance().MarshalManagedToNative(webProxyUserName ?? string.Empty);
			IntPtr nWebProxyPassword = MarshalPtrToUtf8.GetInstance().MarshalManagedToNative(webProxyPassword ?? string.Empty);
			VidyoApplicationSetWebProxyCredentialsNative(objPtr, nWebProxyUserName, nWebProxyPassword);
			Marshal.FreeHGlobal(nWebProxyPassword);
			Marshal.FreeHGlobal(nWebProxyUserName);
		}
		/// <summary>
		/// Start checking for client software updates on the server.
		/// </summary>
		/// <param name="app">The endpoint object.</param>
		/// <param name="currentVersion">Current version of this application.</param>
		/// <param name="workingDirectory">The working directory used to store the installer.</param>
		/// <param name="server">The server to be polled.</param>
		/// <param name="caFilePath"></param>
		/// <param name="webProxyUsername">User name for connecting to web proxy.</param>
		/// <param name="webProxyPassword">Password for connecting to web proxy.</param>
		public Boolean StartUpdateService(String currentVersion, String workingDirectory, String server, String caFilePath, String webProxyUsername, String webProxyPassword) {
			if (objPtr == IntPtr.Zero) { return default; }

			IntPtr nCurrentVersion = MarshalPtrToUtf8.GetInstance().MarshalManagedToNative(currentVersion ?? string.Empty);
			IntPtr nWorkingDirectory = MarshalPtrToUtf8.GetInstance().MarshalManagedToNative(workingDirectory ?? string.Empty);
			IntPtr nServer = MarshalPtrToUtf8.GetInstance().MarshalManagedToNative(server ?? string.Empty);
			IntPtr nCaFilePath = MarshalPtrToUtf8.GetInstance().MarshalManagedToNative(caFilePath ?? string.Empty);
			IntPtr nWebProxyUsername = MarshalPtrToUtf8.GetInstance().MarshalManagedToNative(webProxyUsername ?? string.Empty);
			IntPtr nWebProxyPassword = MarshalPtrToUtf8.GetInstance().MarshalManagedToNative(webProxyPassword ?? string.Empty);
			Boolean ret = VidyoApplicationStartUpdateServiceNative(objPtr, nCurrentVersion, nWorkingDirectory, nServer, nCaFilePath, nWebProxyUsername, nWebProxyPassword);
			Marshal.FreeHGlobal(nWebProxyPassword);
			Marshal.FreeHGlobal(nWebProxyUsername);
			Marshal.FreeHGlobal(nCaFilePath);
			Marshal.FreeHGlobal(nServer);
			Marshal.FreeHGlobal(nWorkingDirectory);
			Marshal.FreeHGlobal(nCurrentVersion);

			return ret;
		}
		/// <summary>
		/// Stop checking for client software updates on the server.
		/// </summary>
		/// <param name="app">The application object.</param>
		public void StopUpdateService() {
			if (objPtr == IntPtr.Zero) { return; }

			VidyoApplicationStopUpdateServiceNative(objPtr);
		}
#if __IOS__
[ObjCRuntime.MonoPInvokeCallback(typeof(DownloadCompletedCallback))]
#endif
		private static void DownloadCompletedCallbackDelegate(IntPtr app, IntPtr version, IntPtr downloadedFile){
			var csAppPtr = app != IntPtr.Zero ? VidyoApplicationGetUserDataNative(app) : IntPtr.Zero;
			if(csAppPtr == IntPtr.Zero) return;
			var csApp = (Application)GCHandle.FromIntPtr(csAppPtr).Target;

			var n_version = VidyoApplicationDownloadCompletedCallbackGetversionCStr(version);

			var n_downloadedFile = VidyoApplicationDownloadCompletedCallbackGetdownloadedFileCStr(downloadedFile);

			csApp?._mIRegisterUpdaterEventListener?.DownloadCompletedCallback((string)MarshalPtrToUtf8.GetInstance().MarshalNativeToManaged(n_version), (string)MarshalPtrToUtf8.GetInstance().MarshalNativeToManaged(n_downloadedFile));
		}
#if __IOS__
[ObjCRuntime.MonoPInvokeCallback(typeof(DownloadFailedCallback))]
#endif
		private static void DownloadFailedCallbackDelegate(IntPtr app, ApplicationDownloadFailedReason reason){
			var csAppPtr = app != IntPtr.Zero ? VidyoApplicationGetUserDataNative(app) : IntPtr.Zero;
			if(csAppPtr == IntPtr.Zero) return;
			var csApp = (Application)GCHandle.FromIntPtr(csAppPtr).Target;

			csApp?._mIRegisterUpdaterEventListener?.DownloadFailedCallback(reason);
		}
	};
}
