using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.IO;
using System.Linq;

namespace Volpe.Cafe.ModelSettings
{
    /// <summary>
    /// Provides information relating to all available compliance scenarios.
    /// </summary>
    [Serializable]
    public class Scenarios
    {
        /// <summary>
        /// Initializes a new instance of the <see cref="Scenarios"/> class using the specified list of scenarios.
        /// </summary>
        /// <param name="scenarioList">A list of scenarios to use for initialization.</param>
        /// <exception cref="ArgumentNullException">
        ///     scenarioList is null, empty, or contain elements that are null.
        /// </exception>
        public Scenarios(IList<Scenario> scenarioList)
        {
            const string scenarioListNullError =
                "Scenario list may not be null, empty, or contain elements that are null.";

            if (scenarioList == null || scenarioList.Count == 0 || scenarioList.Any(item => item == null)) {
                throw new ArgumentNullException(nameof(scenarioList), scenarioListNullError);
            }

            this.ScenarioList = new ReadOnlyCollection<Scenario>(scenarioList);
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="Scenarios"/> class using the specified
        /// <paramref name="scenario"/>.
        /// </summary>
        /// <param name="scenario">A scenario to use for initialization.</param>
        public Scenarios(Scenario scenario) : this(new List<Scenario> { scenario }) { }

        /// <summary>
        /// Gets the compliance scenario at the specified index.
        /// </summary>
        public Scenario this[int index] => this.ScenarioList[index];

        /// <summary>
        /// Gets the baseline compliance scenario.
        /// </summary>
        public Scenario Baseline => this[0];

        /// <summary>
        /// Gets the number of defined compliance scenario.
        /// </summary>
        public int ScenarioCount => this.ScenarioList.Count;

        /// <summary>
        /// Gets a list of compliance scenarios.
        /// </summary>
        public IReadOnlyList<Scenario> ScenarioList { get; private set; }

        /// <summary>
        /// Summarizes the information about this <see cref="Scenarios"/> instance to the specified
        /// <see cref="TextWriter"/>.
        /// </summary>
        public void WriteSummaryInfo(TextWriter writer)
        {
            if (writer == null) {
                return;
            }

            writer.WriteLine("--- Scenarios Analyzed ---");
            if (this.ScenarioList == null || this.ScenarioList.Count == 0) {
                writer.WriteLine("  No compliance scenarios defined.");
            }
            else {
                foreach (Scenario scen in this.ScenarioList) {
                    string baselineStr = (scen.IsBaseline) ? "  (Baseline)" : string.Empty;
                    writer.WriteLine($"  {scen.Index}. {scen.Description}{baselineStr}");
                }
            }
            writer.WriteLine();
        }

    }
}
