using System.Collections.Generic;
using System.IO;
using Volpe.Cafe.Generic;

namespace Volpe.Cafe.MarketData.Design
{
    /// <summary>
    /// Defines the overall industry, containing information about all manufacturers, vehicles, components, and
    /// component families available for modeling.
    /// </summary>
    /// <seealso cref="IManufacturer"/>
    /// <seealso cref="IVehicle"/>
    /// <seealso cref="IPlatform"/>
    /// <seealso cref="IEngine"/>
    /// <seealso cref="ITransmission"/>
    /// <seealso cref="IPlatformFamily"/>
    /// <seealso cref="IEngineFamily"/>
    /// <seealso cref="ITransmissionFamily"/>
    public interface IIndustry : IOEMQueryable
    {
        #region <<< Properties >>>

        /// <summary>
        /// Gets a list of manufacturers that produce vehicles, components, and component families within the industry.
        /// </summary>
        IReadOnlyList<IManufacturer> Manufacturers { get; }

        /// <summary>
        /// Gets a list of vehicles produced by all manufacturers within the industry.
        /// </summary>
        IReadOnlyList<IVehicle> Vehicles { get; }

        /// <summary>
        /// Gets a list of platforms produced by all manufacturers within the industry.
        /// </summary>
        IReadOnlyList<IPlatform> Platforms { get; }
        /// <summary>
        /// Gets a list of engines produced by all manufacturers within the industry.
        /// </summary>
        IReadOnlyList<IEngine> Engines { get; }
        /// <summary>
        /// Gets a list of transmissions produced by all manufacturers within the industry.
        /// </summary>
        IReadOnlyList<ITransmission> Transmissions { get; }

        /// <summary>
        /// Gets a list of platform families produced by all manufacturers within the industry.
        /// </summary>
        IReadOnlyList<IPlatformFamily> PlatformFamilies { get; }
        /// <summary>
        /// Gets a list of engine families produced by all manufacturers within the industry.
        /// </summary>
        IReadOnlyList<IEngineFamily> EngineFamilies { get; }
        /// <summary>
        /// Gets a list of transmission families produced by all manufacturers within the industry.
        /// </summary>
        IReadOnlyList<ITransmissionFamily> TransmissionFamilies { get; }

        /// <summary>
        /// Gets the total number of manufacturers within the industry.
        /// </summary>
        int ManufacturerCount { get; }

        /// <summary>
        /// Gets the domestic minimum passenger car CAFE standard, in miles per gallon (mpg), for the entire industry 
        /// during each model year.
        /// </summary>
        AnnualValue<double> MdpcStandard { get; }

        /// <summary>
        /// Gets the minimum model year available for analysis.
        /// </summary>
        int MinYear { get; }

        /// <summary>
        /// Gets the maximum model year available for analysis.
        /// </summary>
        int MaxYear { get; }

        /// <summary>
        /// Gets whether this <see cref="IIndustry"/> was initialized for analysis.
        /// </summary>
        bool IsInitializedForAnalysis { get; }

        #endregion

        #region <<< Methods >>>

        /// <summary>
        /// Creates a new copy of the <see cref="IIndustry"/> object using the baseline information for the
        /// manufacturers and the various <see cref="IOEMProduct"/>s associated with this instance. All of the
        /// compliance data produced during runtime is discarded.
        /// </summary>
        /// <returns>A new copy of the <see cref="IIndustry"/> object using only the baseline information.</returns>
        /// <remarks>
        /// During modeling, the <see cref="CreateNew"/> method should typically be called on the industry object prior
        /// to starting a new compliance scenario. In iterative based analysis (such as sales model iterations), the
        /// <see cref="CreateNew"/> method should instead be called before each iteration.
        /// </remarks>
        IIndustry CreateNew();

        /// <summary>
        /// Summarizes the information about this <see cref="IIndustry"/> instance using the specified
        /// <see cref="TextWriter"/>.
        /// </summary>
        /// <param name="writer">The <see cref="TextWriter"/> where to write the industry information.</param>
        void WriteSummaryLog(TextWriter writer);

        /// <summary>
        /// Initializes the industry for analysis, including all of the manufacturers contained within the industry.
        /// </summary>
        /// <param name="minYear">The minimum model year available for analysis.</param>
        /// <param name="maxYear">The maximum model year available for analysis.</param>
        void InitializeForAnalysis(int minYear, int maxYear);

        /// <summary>
        /// Searches the list of available manufacturers for a manufacturer with the specified name.
        /// </summary>
        /// <param name="mfrName">The name of the manufacturer to search for.</param>
        /// <returns>
        /// The manufacturer with the specified name, or null, if the manufacturer could not be found.
        /// </returns>
        IManufacturer FindManufacturer(string mfrName);

        //----- filtering for OEMProduct(s) by mfr-name -----
        /// <summary>
        /// Searches the list of available vehicles for all elements that are produced by a manufacturer with the
        /// specified name.
        /// </summary>
        /// <param name="mfrName">The name of the manufacturer to search for.</param>
        /// <returns>
        /// A list of vehicles for the specified manufacturer, or an empty list, if no vehicles could be found.
        /// </returns>
        List<IVehicle> FindVehiclesByMfrName(string mfrName);

        /// <summary>
        /// Searches the list of available platforms for all elements that are produced by a manufacturer with the
        /// specified name.
        /// </summary>
        /// <param name="mfrName">The name of the manufacturer to search for.</param>
        /// <returns>
        /// A list of platforms for the specified manufacturer, or an empty list, if no platforms could be found.
        /// </returns>
        List<IPlatform> FindPlatformsByMfrName(string mfrName);

        /// <summary>
        /// Searches the list of available engines for all elements that are produced by a manufacturer with the
        /// specified name.
        /// </summary>
        /// <param name="mfrName">The name of the manufacturer to search for.</param>
        /// <returns>
        /// A list of engines for the specified manufacturer, or an empty list, if no engines could be found.
        /// </returns>
        List<IEngine> FindEnginesByMfrName(string mfrName);

        /// <summary>
        /// Searches the list of available transmissions for all elements that are produced by a manufacturer with the
        /// specified name.
        /// </summary>
        /// <param name="mfrName">The name of the manufacturer to search for.</param>
        /// <returns>
        /// A list of transmissions for the specified manufacturer, or an empty list, if no transmissions could be
        /// found.
        /// </returns>
        List<ITransmission> FindTransmissionsByMfrName(string mfrName);

        /// <summary>
        /// Searches the list of available platform families for all elements that are produced by a manufacturer with
        /// the specified name.
        /// </summary>
        /// <param name="mfrName">The name of the manufacturer to search for.</param>
        /// <returns>
        /// A list of platform families for the specified manufacturer, or an empty list, if no platform families could
        /// be found.
        /// </returns>
        List<IPlatformFamily> FindPlatformFamiliesByMfrName(string mfrName);

        /// <summary>
        /// Searches the list of available engine families for all elements that are produced by a manufacturer with
        /// the specified name.
        /// </summary>
        /// <param name="mfrName">The name of the manufacturer to search for.</param>
        /// <returns>
        /// A list of engine families for the specified manufacturer, or an empty list, if no engine families could be
        /// found.
        /// </returns>
        List<IEngineFamily> FindEngineFamiliesByMfrName(string mfrName);

        /// <summary>
        /// Searches the list of available transmission families for all elements that are produced by a manufacturer
        /// with the specified name.
        /// </summary>
        /// <param name="mfrName">The name of the manufacturer to search for.</param>
        /// <returns>
        /// A list of transmission families for the specified manufacturer, or an empty list, if no transmission
        /// families could be found.
        /// </returns>
        List<ITransmissionFamily> FindTransmissionFamiliesByMfrName(string mfrName);

        #endregion
    }
}
