using System;
using ZLinq;

namespace Nox.Game {
    public interface ICharacterAttributesFactory {
        EntityAttributes Create(IEntityDefinition entityDefinition);
    }

    public sealed class CharacterAttributesFactory : ICharacterAttributesFactory {
        private readonly IModifierResolver modifierResolver;

        public CharacterAttributesFactory(IModifierResolver modifierResolver) {
            this.modifierResolver = modifierResolver ?? throw new ArgumentNullException(nameof(modifierResolver));
        }

        public EntityAttributes Create(IEntityDefinition entityDefinition) {
            var attributes = entityDefinition.Attributes;

            if(attributes.attributes.AsValueEnumerable().Any(a => a.value <= 0)) {
                throw new ArgumentOutOfRangeException( "attributes cannot be zero or negative.", new ArgumentException() );
            }

            return new EntityAttributes {
                attributes = attributes.attributes.AsValueEnumerable()
                    .Select(a => {
                        var modifiers = modifierResolver.CollectModifiers(entityDefinition, a.attribute);
                        return new Attribute(a.attribute, modifierResolver.Resolve(a.value, modifiers, entityDefinition));
                    })
                    .ToArray()
            };
        }
    }
}
