using System;
using System.Collections.Generic;
using System.Linq;
using Quadarax.Foundation.Core.Console;
using Quadarax.Foundation.Core.QConsole.Argument;
using Quadarax.Foundation.Core.QConsole.Attributes;
using Quadarax.Foundation.Core.QConsole.Command.Base;
using Quadarax.Foundation.Core.QConsole.Value;
using Quadarax.Foundation.Core.Value;

namespace Quadarax.Foundation.Core.QConsole.Command.Defaults
{
    [CommandDefinition]
    public class CmdPrint : AbstractCommand
    {
        public CmdPrint(Engine engine) : base(engine)
        {
        }

        public override string Name => Constants.Commands.Print.Name;
        public override string Description => Constants.Commands.Print.Description;

        protected override IEnumerable<AbstractArgument> OnSetupArguments()
        {
            var arguments = base.OnSetupArguments().ToList();
            arguments.AddRange(
                new AbstractArgument []
                {
                    new OrdinalArgument(0,
                        false,
                        Constants.Commands.Print.ArgCommandValue.Code,
                        Constants.Commands.Print.Description,
                        Constants.Commands.Print.ArgCommandValue.Hint,
                        TypeValuesEnum.String,
                        string.Empty,
                        true),

                    new FlagArgument(Constants.Commands.Print.ArgCommandClipboard.Code,
                        Constants.Commands.Print.ArgCommandClipboard.Description,
                        Constants.Commands.Print.ArgCommandClipboard.Hint,
                        false), 
                });
            return arguments;
        }
        protected override Result OnExecute()
        {
            var result = new Result();
            using (var writerGreen = new ConsoleWriter(ConsoleColor.Green))
            {
                using (var writerYellow = new ConsoleWriter(ConsoleColor.Yellow))
                {
                    var valueArgument = GetArgument(0);
                    var value = valueArgument.Value.AsString();
                    if (!value.StartsWith(QConsole.Defaults.RoleCharacters.SelectionVariablePrefixCharacter))
                        throw new Exception($"Variable is defined as {QConsole.Defaults.RoleCharacters.SelectionVariablePrefixCharacter}<selection_ordinal>.<property_name>");

                    var parts = value.Split(
                        new string[]
                        {
                            QConsole.Defaults.RoleCharacters.SelectionVariablePrefixCharacter,
                            QConsole.Defaults.RoleCharacters.SelectionVariablePropertyCharacter
                        }, StringSplitOptions.RemoveEmptyEntries);
                    if (parts.Length!=2)
                        throw new Exception($"Variable is defined as {QConsole.Defaults.RoleCharacters.SelectionVariablePrefixCharacter}<selection_ordinal>.<property_name>");

                        
                    var ordinal = int.Parse(parts[0]);
                    var selection = Engine.GetSelection(ordinal);
                    if (selection == null)
                        throw new Exception($"Selection variable '{value}' is not defined.");

                    writerGreen.Write(value);
                    writerGreen.Write(" = ");
                    writerYellow.WriteLine(selection.GetPropertyValueAsString(parts[1]));

                    var argument = GetArgument(Constants.Commands.Print.ArgCommandClipboard.Code);
                    if ((bool) argument.Value.Get())
                    {
                        writerGreen.WriteLine("Value was stored in clipboard.");
                    }
                }
            }

            return result;
        }
    }
}
