using System.Collections;

namespace PkmnLib.Dynamic.ScriptHandling;

/// <summary>
/// Iterator to figure out the scripts to run.
/// </summary>
public class ScriptIterator : IEnumerable<ScriptContainer>
{
    private readonly IReadOnlyList<IEnumerable<ScriptContainer>> _scripts;
    private int _currentIndex;

    /// <inheritdoc cref="ScriptIterator"/>
    public ScriptIterator(IReadOnlyList<IEnumerable<ScriptContainer>> scripts)
    {
        _scripts = scripts;
    }

    /// <inheritdoc />
    public IEnumerator<ScriptContainer> GetEnumerator()
    {
        while (_currentIndex < _scripts.Count)
        {
            var enumerable = _scripts[_currentIndex++];
            switch (enumerable)
            {
                case IScriptSet set:
                {
                    // We can't assume that the set remains the same size, so we need to iterate through it
                    // with a for loop.
                    for (var j = 0; j < set.Count; j++)
                    {
                        var script = set.At(j);
                        // We can ignore empty scripts.
                        if (script.IsEmpty)
                            continue;
                        yield return script;
                    }
                    break;
                }
                case ScriptContainer { IsEmpty: true }:
                    continue;
                case ScriptContainer container:
                    yield return container;
                    break;
                default:
                    throw new InvalidOperationException(
                        $"Unexpected script type: {enumerable.GetType().Name}. Expected IScriptSet or ScriptContainer.");
            }
        }
        _currentIndex = 0;
    }

    /// <inheritdoc />
    IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
}