/******************************************************************************/
/*                                                                            */
/* Copyright Avaya LLC.                                                       */
/*                                                                            */
/******************************************************************************/
using Avaya.ClientServices;
using System.Threading.Tasks;

namespace SampleConferenceApp.SDK
{
    /// <summary>
    ///  Class providing support for creation http calls.
    /// </summary>
    class HttpUaCallManager
    {
        #region Private static fields

        private static HttpUaCallManager _httpUaCallManager;
        private static UnifiedPortalService _unifiedPortalService;

        #endregion

        #region Private static methods

        private static void Create()
        {
            if (_httpUaCallManager == null)
            {
                _httpUaCallManager = new HttpUaCallManager();
            }
        }

        #endregion

        #region Public static methods

        public static HttpUaCallManager GetInstance()
        {
            Create();
            return _httpUaCallManager;
        }

        public static void Initialize(UnifiedPortalService unifiedPortalService)
        {
            Create();
            _unifiedPortalService = unifiedPortalService;
        }

        #endregion

        #region Public methods

        /// <summary>
        /// Creates http call and added events handler to call object.
        /// </summary>
        public async Task<UnifiedPortalErrorEventArgs> CreateHttpCall(AppCallCreationInfo appCallCreationInfo)
        {
            var joinMeetingResult = await RequestToJoinMeeting(appCallCreationInfo);

            if (joinMeetingResult.Error != null)
            {
                return joinMeetingResult.Error;
            }

            var callCreationInfo = new CallCreationInfo(
                appCallCreationInfo.ConferenceId,
                "",
                joinMeetingResult.UnifiedPortalMeetingInfo.PortalToken,
                joinMeetingResult.UnifiedPortalMeetingInfo.UccpURL,
                joinMeetingResult.UnifiedPortalMeetingInfo.ServiceGatewayURL,
                appCallCreationInfo.PortalUrl,
                appCallCreationInfo.Username,
                appCallCreationInfo.ConferenceId,
                false);

            callCreationInfo.CallType = CallType.CallTypeHttpMeetMe;

            // Create a call object according to CallCreationInfo
            CallManager.GetInstance().CreateAudioCall(callCreationInfo);
            return null;
        }

        #endregion

        #region Private methods

        private async Task<AppJoinMeetingResult> RequestToJoinMeeting(AppCallCreationInfo appCallCreationInfo)
        {
            var taskCompletionSource = new TaskCompletionSource<AppJoinMeetingResult>();

            // Create Unified Portal configuration
            var portalConfig = new UnifiedPortalConfiguration
            {
                AuthenticationMethodPreferences = new[] { AuthenticationMethod.BasicOrDigest },
                // Optionally, specify credential provider to sign in portal and join the meeting as signed in user.
                CredentialProvider = appCallCreationInfo.ShouldLoginAsGuest ? null : new CredentialProvider(appCallCreationInfo.Username, appCallCreationInfo.Password),
                // Specify Unified Portal URL (mandatory)
                ServerURL = appCallCreationInfo.PortalUrl
            };

            // Retrieve the token and other meeting details
            _unifiedPortalService.RequestToJoinMeeting(
                portalConfig,
                appCallCreationInfo.ConferenceId,
                appCallCreationInfo.Username,
                false,
                "",
                "",
                (info, error) => taskCompletionSource.SetResult(new AppJoinMeetingResult() { UnifiedPortalMeetingInfo = info, Error = error }));

            return await taskCompletionSource.Task;
        }

        #endregion
    }
}
