// ApiCallsBuilder.cs

using System;
using System.Collections.Generic;
using System.Net;

namespace Beam.Api;
    /// <summary>
    /// Fluent builder for <see cref="ApiCalls"/>.
    /// </summary>
    public sealed class ApiCallsBuilder {
        private readonly List<ApiCall> _calls = [];
        private int? _parallelism = 1; // default = sequential

        public ApiCallsBuilder Add(ApiCall call) {
            _calls.Add(call ?? throw new ArgumentNullException(nameof(call)));
            return this;
        }

        public ApiCallsBuilder AddRange(IEnumerable<ApiCall> calls) {
            _calls.AddRange(calls ?? throw new ArgumentNullException(nameof(calls)));
            return this;
        }

        /// <summary>Adds the same <paramref name="prototype"/> call <paramref name="times"/> times.</summary>
        public ApiCallsBuilder Repeat(ApiCall prototype, int times) {
            if (times < 1) throw new ArgumentOutOfRangeException(nameof(times));
            for (var i = 0; i < times; i++)
                Add(prototype);
            return this;
        }

        /// <summary>Run with the specified degree of parallelism (≥ 1).</summary>
        public ApiCallsBuilder UseParallel(int maxDegree) => SetDegree(Math.Max(1, maxDegree));

        /// <summary>Run sequentially (same as <c>UseParallel(1)</c>).</summary>
        public ApiCallsBuilder UseSequential() => SetDegree(1);

        private ApiCallsBuilder SetDegree(int degree) {
            _parallelism = degree;
            return this;
        }

        public ApiCalls Build() {
            if (_calls.Count == 0)
                throw new InvalidOperationException("At least one ApiCall is required.");
            return new ApiCalls(_calls, _parallelism);
        }
    }