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

namespace Volpe.Cafe.MarketData.Design
{
    /// <summary>
    /// Defines methods for querying data from original equipment manufacturers (OEMs).
    /// </summary>
    public interface IOEMQueryable
    {
        #region <<< Properties >>>

        /// <summary>
        /// Gets the total number of available vehicles.
        /// </summary>
        int VehicleCount { get; }

        /// <summary>
        /// Gets the total number of available platforms.
        /// </summary>
        int PlatformCount { get; }
        /// <summary>
        /// Gets the total number of available engines.
        /// </summary>
        int EngineCount { get; }
        /// <summary>
        /// Gets the total number of available transmissions.
        /// </summary>
        int TransmissionCount { get; }

        /// <summary>
        /// Gets the total number of available platform families.
        /// </summary>
        int PlatformFamilyCount { get; }
        /// <summary>
        /// Gets the total number of available engine families.
        /// </summary>
        int EngineFamilyCount { get; }
        /// <summary>
        /// Gets the total number of available transmission families.
        /// </summary>
        int TransmissionFamilyCount { get; }

        #endregion

        #region <<< Methods >>>

        //----- filtering for Vehicle(s) by component code -----
        /// <summary>
        /// Searches the list of available vehicles for all elements that use a platform with the specified platform
        /// code.
        /// </summary>
        /// <param name="code">The platform code to search for.</param>
        /// <returns>
        /// A list of vehicles that use a platform with the specified platform code, or an empty list, if no vehicles
        /// could be found.
        /// </returns>
        List<IVehicle> FindVehiclesByPlatformCode(int code);

        /// <summary>
        /// Searches the list of available vehicles for all elements that use an engine with the specified engine code.
        /// </summary>
        /// <param name="code">The engine code to search for.</param>
        /// <returns>
        /// A list of vehicles that use an engine with the specified engine code, or an empty list, if no vehicles
        /// could be found.
        /// </returns>
        List<IVehicle> FindVehiclesByEngineCode(int code);

        /// <summary>
        /// Searches the list of available vehicles for all elements that use a transmission with the specified
        /// transmission code.
        /// </summary>
        /// <param name="code">The transmission code to search for.</param>
        /// <returns>
        /// A list of vehicles that use a transmission with the specified transmission code, or an empty list, if no
        /// vehicles could be found.
        /// </returns>
        List<IVehicle> FindVehiclesByTransmissionCode(int code);

        //----- filtering for OEMProduct by product code -----
        /// <summary>
        /// Searches the list of available vehicles for a <see cref="IVehicle"/> with the specified code.
        /// </summary>
        /// <param name="code">The vehicle code to search for.</param>
        /// <returns>
        /// The vehicle with the specified code, or null, if the vehicle could not be found.
        /// </returns>
        IVehicle FindVehicleByCode(int code);

        /// <summary>
        /// Searches the list of available platforms for a <see cref="IPlatform"/> with the specified code.
        /// </summary>
        /// <param name="code">The platform code to search for.</param>
        /// <returns>
        /// The platform with the specified code, or null, if the platform could not be found.
        /// </returns>
        IPlatform FindPlatformByCode(int code);

        /// <summary>
        /// Searches the list of available engines for an <see cref="IEngine"/> with the specified code.
        /// </summary>
        /// <param name="code">The engine code to search for.</param>
        /// <returns>
        /// The engine with the specified code, or null, if the engine could not be found.
        /// </returns>
        IEngine FindEngineByCode(int code);

        /// <summary>
        /// Searches the list of available transmissions for a <see cref="ITransmission"/> with the specified code.
        /// </summary>
        /// <param name="code">The transmission code to search for.</param>
        /// <returns>
        /// The transmission with the specified code, or null, if the transmission could not be found.
        /// </returns>
        ITransmission FindTransmissionByCode(int code);

        /// <summary>
        /// Searches the list of available platform families for a <see cref="IPlatformFamily"/> with the specified
        /// code.
        /// </summary>
        /// <param name="code">The platform family code to search for.</param>
        /// <returns>
        /// The platform family with the specified code, or null, if the platform family could not be found.
        /// </returns>
        IPlatformFamily FindPlatformFamilyByCode(int code);

        /// <summary>
        /// Searches the list of available engine families for an <see cref="IEngineFamily"/> with the specified code.
        /// </summary>
        /// <param name="code">The engine family code to search for.</param>
        /// <returns>
        /// The engine family with the specified code, or null, if the engine family could not be found.
        /// </returns>
        IEngineFamily FindEngineFamilyByCode(int code);

        /// <summary>
        /// Searches the list of available transmission families for a <see cref="ITransmissionFamily"/> with the
        /// specified code.
        /// </summary>
        /// <param name="code">The transmission family code to search for.</param>
        /// <returns>
        /// The transmission family with the specified code, or null, if the transmission family could not be found.
        /// </returns>
        ITransmissionFamily FindTransmissionFamilyByCode(int code);

        //----- filtering for OEMComponentFamily by family name -----
        /// <summary>
        /// Searches the list of available platform families for a <see cref="IPlatformFamily"/> with the specified
        /// name.
        /// </summary>
        /// <param name="familyName">The name of the platform family to search for.</param>
        /// <returns>
        /// The platform family with the specified name, or null, if the platform family could not be found.
        /// </returns>
        IPlatformFamily FindPlatformFamilyByName(string familyName);

        /// <summary>
        /// Searches the list of available engine families for an <see cref="IEngineFamily"/> with the specified name.
        /// </summary>
        /// <param name="familyName">The name of the engine family to search for.</param>
        /// <returns>
        /// The engine family with the specified name, or null, if the engine family could not be found.
        /// </returns>
        IEngineFamily FindEngineFamilyByName(string familyName);

        /// <summary>
        /// Searches the list of available transmission families for a <see cref="ITransmissionFamily"/> with the
        /// specified name.
        /// </summary>
        /// <param name="familyName">The name of the transmission family to search for.</param>
        /// <returns>
        /// The transmission family with the specified name, or null, if the transmission family could not be found.
        /// </returns>
        ITransmissionFamily FindTransmissionFamilyByName(string familyName);

        //----- filtering for OEMComponent(s) by family name -----
        /// <summary>
        /// Searches the list of available platforms for all elements that belong to a platform family with the
        /// specified family name.
        /// </summary>
        /// <param name="familyName">The name of the platform family to search for.</param>
        /// <returns>
        /// A list of platforms with the specified family name, or an empty list, if no platforms could be found.
        /// </returns>
        List<IPlatform> FindPlatformsByFamilyName(string familyName);

        /// <summary>
        /// Searches the list of available engines for all elements that belong to an engine family with the specified
        /// family name.
        /// </summary>
        /// <param name="familyName">The name of the engine family to search for.</param>
        /// <returns>
        /// A list of engines with the specified family name, or an empty list, if no engines could be found.
        /// </returns>
        List<IEngine> FindEnginesByFamilyName(string familyName);

        /// <summary>
        /// Searches the list of available transmissions for all elements that belong to a transmission family with the
        /// specified family name.
        /// </summary>
        /// <param name="familyName">The name of the transmission family to search for.</param>
        /// <returns>
        /// A list of transmissions with the specified family name, or an empty list, if no transmissions could be
        /// found.
        /// </returns>
        List<ITransmission> FindTransmissionsByFamilyName(string familyName);

        //----- statistics about mix of vehicles -----
        /// <summary>
        /// Calculates the variety of regulatory classes during the specified model year, based on the list of vehicles
        /// available within this instance. If <paramref name="year"/> is null, the mix of regulatory classes will be
        /// obtained based on the vehicle's baseline state instead.
        /// </summary>
        /// <param name="year">
        ///     The model year for which to compute a mix of regulatory classes, or null to compute the mix based on
        ///     the vehicle's baseline state.
        /// </param>
        /// <returns>
        /// An object specifying a mix of regulatory classes of all available vehicles.
        /// </returns>
        RCValue<bool> CalcRegClassMix(int? year = null);

        /// <summary>
        /// Calculates the variety of regulatory classes during the specified model year, based on the list of vehicles
        /// available within this instance, where the domestic and imported cars are treated as a single passenger car
        /// regulatory class. If <paramref name="year"/> is null, the mix of regulatory classes will be obtained based
        /// on the vehicle's baseline state instead.
        /// </summary>
        /// <param name="year">
        ///     The model year for which to compute a mix of regulatory classes, or null to compute the mix based on
        ///     the vehicle's baseline state.
        /// </param>
        /// <returns>
        /// An object specifying a mix of regulatory classes of all available vehicles.
        /// </returns>
        RCAltValue<bool> CalcAltRegClassMix(int? year = null);

        /// <summary>
        /// Calculates the variety of vehicle classes during the specified model year, based on the list of vehicles
        /// available within this instance. If <paramref name="year"/> is null, the mix of vehicle classes will be
        /// obtained based on the vehicle's baseline state instead.
        /// </summary>
        /// <param name="year">
        ///     The model year for which to compute a mix of vehicle classes, or null to compute the mix based on the
        ///     vehicle's baseline state.
        /// </param>
        /// <returns>
        /// An object specifying a mix of vehicle classes of all available vehicles.
        /// </returns>
        VCValue<bool> CalcVehClassMix(int? year = null);

        /// <summary>
        /// Calculates the variety of fuel types during the specified model year, based on the list of vehicles
        /// available within this instance. If <paramref name="year"/> is null, the mix of fuel types will be obtained
        /// based on the vehicle's baseline state instead.
        /// </summary>
        /// <param name="year">
        ///     The model year for which to compute a mix of fuel types, or null to compute the mix based on the
        ///     vehicle's baseline state.
        /// </param>
        /// <returns>
        /// An object specifying a mix of fuel types of all available vehicles.
        /// </returns>
        FTValue<bool> CalcFuelTypeMix(int? year = null);

        #endregion
    }
}
