using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Timers;
using Tango.Core.DI;
using Tango.Core.ExtensionMethods;
using Tango.FSE.BL.Web;
using Tango.FSE.Common;
using Tango.FSE.Common.Authentication;
using Tango.FSE.Common.Build;
using Tango.FSE.Common.DemoMode;
using Tango.FSE.Common.FSEApplication;
using Tango.FSE.Common.Notifications;
using Tango.FSE.Common.Threading;
using Tango.FSE.Common.Updates;
using Tango.FSE.UI.Dialogs;
using Tango.FSE.Web.Messages;
namespace Tango.FSE.UI.Updates
{
///
/// Represents the default implementation.
///
///
[TangoCreateWhenRegistered]
public class DefaultUpdatesManager : FSEExtendedObject, IUpdatesManager
{
private Timer _autoUpdateCheckTimer;
private const double AUTO_UPDATE_CHECK_INTERVAL_MINUTES = 30;
private bool _performedFirstCheck;
[TangoInject]
private FSEWebClient WebClient { get; set; }
[TangoInject]
private IFSEApplicationManager ApplicationManager { get; set; }
[TangoInject]
private INotificationProvider NotificationProvider { get; set; }
[TangoInject]
private IDispatcherProvider DispatcherProvider { get; set; }
[TangoInject]
private IAuthenticationProvider AuthenticationProvider { get; set; }
[TangoInject(TangoInjectMode.WhenAvailable)]
private IDemoModeManager DemoModeManager { get; set; }
[TangoInject]
private IBuildProvider BuildProvider { get; set; }
///
/// Gets or sets a value indicating whether to perform an automatic update checks.
///
public bool AutoCheckForUpdates { get; set; }
///
/// Gets or sets the automatic update check interval.
///
public TimeSpan AutoUpdateCheckInterval { get; set; }
///
/// Initializes a new instance of the class.
///
public DefaultUpdatesManager()
{
_autoUpdateCheckTimer = new Timer(TimeSpan.FromMinutes(AUTO_UPDATE_CHECK_INTERVAL_MINUTES).TotalMilliseconds);
_autoUpdateCheckTimer.Elapsed += _autoUpdateCheckTimer_Elapsed;
_autoUpdateCheckTimer.Stop();
}
///
/// Checks for updates and returns a response containing the relevant blob/cdn addresses.
///
///
public async Task CheckForUpdates()
{
try
{
LogManager.Log("Checking for updates...");
var appVersion = ApplicationManager.Version;
var response = await WebClient.CheckForUpdates(new CheckForUpdatesRequest()
{
Version = appVersion.ToString(),
Build = Tango.FSE.BL.BuildProvider.Build
});
LogManager.Log($"Update check response received:\n{response.ToJsonString()}");
return response;
}
catch (Exception ex)
{
throw LogManager.Log(ex, "Error checking for updates.");
}
}
///
/// Called when is ready and user is logged-in. (happens every time a user logs-in)
///
public async void OnApplicationReady(IFSEApplicationManager applicationManager)
{
if (!_performedFirstCheck)
{
_performedFirstCheck = true;
if (!applicationManager.DemoMode)
{
try
{
await Task.Delay(3000);
LogManager.Log("Performing first application update check...");
var response = await CheckForUpdates();
if (response.IsUpdateAvailable)
{
LogManager.Log("Update is available. Invoking application update dialog...");
DisplayApplicationUpdateDialog(response);
}
}
catch
{
LogManager.Log("First application run update check failed.");
}
}
}
_autoUpdateCheckTimer.Start();
if (applicationManager.DemoMode)
{
DemoModeManager.InsertCommand(async () =>
{
await CheckForUpdatesWithDialog();
}, "Emulate Application Update", "Emulates an application update snackbar notification.");
}
}
private async void _autoUpdateCheckTimer_Elapsed(object sender, ElapsedEventArgs e)
{
_autoUpdateCheckTimer.Stop();
if (Settings.AutoCheckForUpdates)
{
await CheckForUpdatesWithDialog();
}
_autoUpdateCheckTimer.Start();
}
private async Task CheckForUpdatesWithDialog()
{
try
{
LogManager.Log("Performing automatic update check...");
var response = await CheckForUpdates();
if (response.IsUpdateAvailable)
{
LogManager.Log("Application update is available. Pushing snackbar item...");
DispatcherProvider.Invoke(() =>
{
NotificationProvider.PushSnackbarItem(
MessageType.ApplicationUpdate,
"Application Update",
true,
$"New version of {BuildProvider.BuildName} is available\nTap to see more details.",
TimeSpan.FromMinutes(5),
null,
() =>
{
LogManager.Log("Application update snackbar item pressed. Invoking application update dialog...");
DisplayApplicationUpdateDialog(response);
});
});
}
}
catch
{
LogManager.Log("Automatic update check failed.");
}
}
private void DisplayApplicationUpdateDialog(CheckForUpdatesResponse response)
{
DispatcherProvider.Invoke(async () =>
{
var vm = await NotificationProvider.ShowDialog(new ApplicationUpdateViewVM()
{
Version = Version.Parse(response.Version).ToString(3),
Comments = response.Comments
});
if (vm.DialogResult)
{
Process.Start(AuthenticationProvider.CurrentEnvironment.MachineServiceAddress + $"/fse?buildVariant={(int)BuildProvider.CurrentBuild}");
}
});
}
}
}