using eSuite.WorkBench.Services;
using eSuite.WorkBench.WpfHelper;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using eSuite.WorkBench.Models;

namespace eSuite.WorkBench.Commands
{
    public class StartContainersCommand : AsyncCommandBase
    {
        private readonly MainWindowViewModel _mainWindowViewModel;
        private readonly ICommandsService _commandService;
        public StartContainersCommand(MainWindowViewModel mainWindowViewModel, ICommandsService commandsService, Action<Exception> onException, EventHandler<FeedbackEventArgs> addFeedbackMessage ) : base(onException)
        {
            FeedbackMessage += addFeedbackMessage;
            _mainWindowViewModel = mainWindowViewModel;
            _commandService = commandsService;
            _commandService.FeedbackMessage += commandService_FeedbackMessage;

            IsEnabled = !_commandService.IsAnyContainerRunning();
        }

        private void commandService_FeedbackMessage(object sender, FeedbackEventArgs e)
        {
            DoFeedbackMessage(e.Message);
        }

        public StartContainersCommand(MainWindowViewModel mainWindowViewModel, ICommandsService commandsService, Action<Exception> onException) : base (onException)
        {
            _mainWindowViewModel = mainWindowViewModel;
            _commandService = commandsService;

            IsEnabled = !_commandService.IsAnyContainerRunning();
        }

        protected override async Task ExecuteAsync(object parameter)
        {
            try
            {
                DoFeedbackMessage("Starting containers...");
                DoFeedbackMessage("Connecting to container registry");
                await _commandService.ConnectToContainerRegistry();

                var databaseName = GetBranchName(_mainWindowViewModel.SelectedBranch);

                DoFeedbackMessage($"Database name: {databaseName}");

                await Task.WhenAll(new List<Task>
                {
                    _commandService.StartRabbitMQContainerAsync(),
                    _commandService.StartDatabaseMigratorContainerAsync(_mainWindowViewModel.AvailableDbMigratorTags.SelectedItem, databaseName),
                });
                
                await Task.WhenAll(new List<Task>
                {
                    _commandService.StartProxyContainerAsync(_mainWindowViewModel.AvailableProxyTags.SelectedItem),
                    _commandService.StartApiContainerAsync(_mainWindowViewModel.AvailableApiTags.SelectedItem, databaseName),
                    _commandService.StartWebUiContainerAsync(_mainWindowViewModel.AvailableWebUiTags.SelectedItem),
                    _commandService.StartSchedulerContainerAsync(_mainWindowViewModel.AvailableSchedulerTags.SelectedItem, databaseName),
                    _commandService.StartMessageProcessorContainerAsync(_mainWindowViewModel.AvailableMessageProcessorTags.SelectedItem, databaseName)
                });

                _mainWindowViewModel.StopContainersCommand.IsEnabled = await _commandService.IsAnyContainerRunningAsync();
                IsEnabled = !(await _commandService.IsAnyContainerRunningAsync());
            }
            catch (Exception ex)
            {
                DoFeedbackMessage(ex.Message);
            }
            finally
            {
                DoFeedbackMessage("...finished");
            }

        }

        private static string GetBranchName(Branch branch)
        {
            char[] replaceChars = { '.', '-' };

            var currentBranch = branch;
            var branchName = string.Empty;

            while (currentBranch != null)
            {
                branchName = currentBranch.BranchName + "_" + branchName;
                currentBranch = currentBranch.Parent;
            }

            foreach (var replaceChar in replaceChars)
                branchName = branchName.Replace(replaceChar, '_');

            return branchName.TrimEnd('_');
        }
    }
}
