using System;
using System.Collections.Generic;
using Quadarax.Foundation.Core.QConsole;
using Quadarax.Foundation.Core.QConsole.Argument;
using Quadarax.Foundation.Core.QConsole.Value;
// ReSharper disable InconsistentNaming

namespace BO.Console.Commands.Base
{
    internal abstract class AbstractListScopedCommand<TScopeEnum> : AbstractListCommand
    {
        #region *** Constants ***

        private const string CS_ARG_NAME_SCOPE = "scope";
        private const string CS_ARG_HINT_SCOPE = "<scope>";
        private const string CS_ARG_DESC_SCOPE = "Scope to filter: {0}. Must be one value.";

        #endregion

        #region *** Private Fields ***

        protected TScopeEnum Scope { get; private set; }
        #endregion

        #region *** Constructors ***
        protected AbstractListScopedCommand(Engine engine) : base(engine)
        {
        }
        #endregion


        #region *** Protected Overrides ***

        protected override void OnValidateArguments()
        {
            base.OnValidateArguments();
            var scope = GetArgumentValueOrDefault<string>(CS_ARG_NAME_SCOPE);
            if (!Enum.TryParse(typeof(TScopeEnum), scope, true, out var res))
                throw new ArgumentException(
                    $"Argument {Engine.Configuration.CharacterNamedArgumentSeparator}{CS_ARG_NAME_SCOPE} invalid value. Must be one of: {string.Join(", ", Enum.GetNames(typeof(TScopeEnum)))} !",
                    nameof(CS_ARG_NAME_SCOPE));
            Scope = (TScopeEnum)res;
        }

        protected override IEnumerable<AbstractArgument> OnSetupArguments()
        {
            var args =  new List<AbstractArgument>(base.OnSetupArguments());
            args.Add(new NamedArgument(CS_ARG_NAME_SCOPE, string.Format(CS_ARG_DESC_SCOPE, string.Join(", ", Enum.GetNames(typeof(TScopeEnum)))), CS_ARG_HINT_SCOPE,TypeValuesEnum.String,string.Empty,true));
            return args;
        }
        #endregion
    }
}
