using System;
using System.Collections.Generic;
using System.Linq;

namespace FishDice.LuckyDice
{
    public sealed class RollActionDispatcher
    {
        private readonly Dictionary<string, IRollActionExecutor> _executors;

        public RollActionDispatcher(IEnumerable<IRollActionExecutor> executors)
        {
            if (executors == null)
            {
                throw new ArgumentNullException(nameof(executors));
            }

            _executors = executors.ToDictionary(executor => executor.ActionType, executor => executor);
        }

        public IReadOnlyList<RollActionResult> Execute(
            RollActionContext context,
            IReadOnlyList<RollActionSpec> actions)
        {
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }

            if (actions == null)
            {
                return Array.Empty<RollActionResult>();
            }

            var results = new List<RollActionResult>(actions.Count);
            foreach (var action in actions)
            {
                var result = ExecuteSingle(context, action);
                results.Add(result);
                context.Trace.RecordActionResult(result);
            }

            return results;
        }

        private RollActionResult ExecuteSingle(RollActionContext context, RollActionSpec action)
        {
            if (!_executors.TryGetValue(action.ActionType, out var executor))
            {
                return RollActionResult.Failure(
                    action.ActionType,
                    "No executor registered for action type: " + action.ActionType);
            }

            return executor.Execute(context, action);
        }
    }
}
