using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using BO.AppServer.Metadata.Dto;
using BO.Console.Commands.Base;
using Quadarax.Foundation.Core.QConsole;
using Quadarax.Foundation.Core.QConsole.Argument;
using Quadarax.Foundation.Core.QConsole.Attributes;
using Quadarax.Foundation.Core.Value;

namespace BO.Console.Commands.Service
{
    [CommandDefinition]
    internal class VersionCommand : AbstractListCommand
    {
        #region *** Constants ***
        private const string CS_CMD_VERSIONGET_NAME = "version";
        private const string CS_CMD_VERSIONGET_DESCR = "Get version information from server or from console.";


        private const string CS_ARG_NAME_LOCAL = "local";
        private const string CS_ARG_HINT_LOCAL = "<show_local>";
        private const string CS_ARG_DESC_LOCAL = "Flag if set shows only local console assembly manifest.";

        
        #endregion

        #region *** Properties ***

        public override string Name => CS_CMD_VERSIONGET_NAME;
        public override string Description => CS_CMD_VERSIONGET_DESCR;

        #endregion

        #region *** Constructor ***
        public VersionCommand(Engine engine) : base(engine)
        {
        }
        #endregion

        #region *** EXECUTE ***
        protected override Result OnExecute()
        {

            IEnumerable<AssemblyInfoDto> versions;
            if (!WasArgumentSpecified(CS_ARG_NAME_LOCAL))
            {
                versions = Client.GetVersionsAsync().Result.OrderBy(x=>x.Name);
                WriteDtoToConsole(versions, "Name", "AssemblyVersion","FileVersion");
            }
            else
            {
                var assemblies = AppDomain.CurrentDomain.GetAssemblies();
                versions = new List<AssemblyInfoDto>();
                foreach (var assembly in assemblies)
                {
                    var fiv = FileVersionInfo.GetVersionInfo(assembly.Location);
                    ((List<AssemblyInfoDto>)versions).Add(new AssemblyInfoDto()
                    {
                        FileVersion = fiv.FileVersion,
                        AssemblyVersion = assembly.GetName().Version?.ToString(),
                        Name = assembly.GetName().Name
                    });
                }

                versions = versions.OrderBy(x => x.Name).ToList();

            }
            WriteDtoToConsole(versions, "Name", "AssemblyVersion","FileVersion");                
            return new Result();
        }
        #endregion

        #region *** Private operations ***

        protected override void OnInitialize()
        {
            if (!WasArgumentSpecified(CS_ARG_NAME_LOCAL))
                base.OnInitialize();
        }

        protected override IEnumerable<AbstractArgument> OnSetupArguments()
        {
            var args =  base.OnSetupArguments().ToList();
            args.Add(new FlagArgument(CS_ARG_NAME_LOCAL, CS_ARG_DESC_LOCAL, CS_ARG_HINT_LOCAL,false));
            return args;
        }

        #endregion
    }
}
