using System;
using System.IO;

namespace Volpe.Cafe.ModelSettings
{
    /// <summary>
    /// Provides an overall view of modeling configuration settings.
    /// </summary>
    [Serializable]
    public sealed class ModelingSettings
    {
        /// <summary>
        /// Initializes a new instance of the <see cref="ModelingSettings"/> class.
        /// </summary>
        public ModelingSettings() : this(new IOSettings(true), new RuntimeSettings(true)) { }

        /// <summary>
        /// Initializes a new instance of the <see cref="ModelingSettings"/> class, using the specified I/O and runtime
        /// settings.
        /// </summary>
        public ModelingSettings(IOSettings ioSettings, RuntimeSettings runtimeSettings)
        {
            this.IOSettings = ioSettings;
            this.RuntimeSettings = runtimeSettings;
        }


        /// <summary>
        /// Gets the locations of the input data files for use with the modeling system as well as the directory where
        /// the modeling results will be saved.
        /// </summary>
        public IOSettings IOSettings { get; private set; }
        /// <summary>
        /// Gets the additional modeling options, as selected by the user during model's runtime, to further customize
        /// the model behavior, beyond what is available in the input files.
        /// </summary>
        public RuntimeSettings RuntimeSettings { get; private set; }

        /// <summary>
        /// Gets or sets information relating to all available vehicle technologies, containing technology definitions,
        /// attributes, and costs for all vehicle- and engine-technology classes.
        /// </summary>
        public Technologies Technologies { get; set; }
        /// <summary>Gets or sets the compliance and effects parameters for the modeling system.</summary>
        public Parameters Parameters { get; set; }
        /// <summary>Gets or sets information relating to all available compliance scenarios.</summary>
        public Scenarios Scenarios { get; set; }

        /// <summary>
        /// Gets whether this <see cref="ModelingSettings"/> instance has a valid <see cref="Technologies"/> object
        /// defined.
        /// </summary>
        public bool HasTechnologies => this.Technologies != null && this.Technologies.TechnologyCount > 0;
        /// <summary>
        /// Gets whether this <see cref="ModelingSettings"/> instance has a valid <see cref="Parameters"/> object
        /// defined.
        /// </summary>
        public bool HasParameters => this.Parameters != null;
        /// <summary>
        /// Gets whether this <see cref="ModelingSettings"/> instance has a valid <see cref="Scenarios"/> object
        /// defined.
        /// </summary>
        public bool HasScenarios => this.Scenarios != null && this.Scenarios.ScenarioCount > 0;


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

            writer.WriteLine("---------- Modeling Settings ----------");
            this.IOSettings?.WriteSummaryInfo(writer);
            this.RuntimeSettings?.WriteSummaryInfo(writer);
            this.Technologies?.WriteSummaryInfo(writer);
            this.Scenarios?.WriteSummaryInfo(writer);
        }

    }
}
