using System;
using Volpe.Cafe.Generic;
using Volpe.Cafe.MarketData.BaselineInfo;

namespace Volpe.Cafe.MarketData.Design
{
    /// <summary>
    /// Defines a vehicle model that encapsulates a description of its engineering characteristics as well as provides
    /// an annual historic view of its revisions.
    /// </summary>
    /// <seealso cref="IVehicleInfo"/>
    /// <seealso cref="IVehicleRevision"/>
    public interface IVehicle : IOEMProduct, IVehicleInfo
    {
        /// <summary>
        /// Gets a description of baseline engineering characteristics for the vehicle.
        /// </summary>
        new BaselineVehicle BaselineInfo { get; }

        /// <summary>
        /// Gets the product information for the latest revision of the vehicle, or the vehicle's baseline engineering
        /// characteristics if no new revisions have been created yet.
        /// </summary>
        new IVehicleRevision RevisionInfo { get; }

        /// <summary>
        /// Gets an annual stream of <see cref="IVehicleRevision"/> objects, containing revisions of vehicle's
        /// engineering characteristics and compliance attributes.
        /// </summary>
        new IAnnualValue<IVehicleRevision> Revisions { get; }

        /// <summary>
        /// Gets the platform used by the vehicle.
        /// </summary>
        IPlatform Platform { get; }

        /// <summary>
        /// Gets the engine used by the vehicle.
        /// </summary>
        IEngine Engine { get; }

        /// <summary>
        /// Gets the transmission used by the vehicle.
        /// </summary>
        ITransmission Transmission { get; }

        /// <summary>
        /// Gets the vehicle that serves as the reference vehicle for shifting sales as part of complying with the ZEV
        /// requirements, or null, if this vehicle does not have a ZEV reference.
        /// </summary>
        /// <seealso cref="IVehicleInfo.ZevReferenceVehicleCode"/>
        IVehicle ZevReferenceVehicle { get; }


        /// <summary>
        /// Advances the revision year for the vehicle by one, and creates a new vehicle revision for that year.
        /// </summary>
        /// <returns>
        /// A <see cref="IVehicleRevision"/> object containing revision information for the new revision year.
        /// </returns>
        /// <remarks>
        /// This method must be called by the compliance model at the start of each new model year. That is, a vehicle
        /// revision must be created for a given model year, before analysis of that year can begin.
        /// </remarks>
        /// <exception cref="InvalidOperationException">
        ///     The vehicle must be initialized for analysis before vehicle revisions may be created.
        ///     -or-
        ///     A vehicle revision may not be created for a model year beyond the last analysis year.
        /// </exception>
        new IVehicleRevision CreateRevision();

        /// <summary>
        /// Obtains a vehicle revision for the specified model year.
        /// </summary>
        /// <param name="year">
        ///     The model year for which to obtain a vehicle revision; or, specify null to return the vehicle's latest
        ///     revision.
        /// </param>
        /// <returns>
        /// A vehicle revision for the specified model year, or null, if the vehicle does not have any revisions.
        /// </returns>
        /// <exception cref="ArgumentOutOfRangeException">
        ///     The specified year is out-of-bounds of the minimum and maximum range of model years available for
        ///     analysis.
        /// </exception>
        new IVehicleRevision GetRevision(int? year = null);

        /// <summary>
        /// Searches for a platform revision that the vehicle uses during the given model year.
        /// </summary>
        /// <param name="year">The model year of the vehicle's revisions to search.</param>
        /// <param name="closestMatch">
        ///     true, to search for a platform revision that is closest to the vehicle's state;
        ///     false, to search for an exact match.
        /// </param>
        /// <returns>The platform revision that the vehicle uses, or null, if a match could not be found.</returns>
        IOEMComponentRevision GetPlatformRevision(int year, bool closestMatch = false);

        /// <summary>
        /// Searches for an engine revision that the vehicle uses during the given model year.
        /// </summary>
        /// <param name="year">The model year of the vehicle's revisions to search.</param>
        /// <param name="closestMatch">
        ///     true, to search for an engine revision that is closest to the vehicle's state;
        ///     false, to search for an exact match.
        /// </param>
        /// <returns>The engine revision that the vehicle uses, or null, if a match could not be found.</returns>
        IOEMComponentRevision GetEngineRevision(int year, bool closestMatch = false);

        /// <summary>
        /// Searches for a transmission revisions that the vehicle uses during the given model year.
        /// </summary>
        /// <param name="year">The model year of the vehicle's revisions to search.</param>
        /// <param name="closestMatch">
        ///     true, to search for a transmission revision that is closest to the vehicle's state;
        ///     false, to search for an exact match.
        /// </param>
        /// <returns>The transmission revision that the vehicle uses, or null, if a match could not be found.</returns>
        IOEMComponentRevision GetTransmissionRevision(int year, bool closestMatch = false);


        /// <summary>
        /// Removes the vehicle's engine.
        /// <br/><br/>
        /// NOTE:
        /// The ClearEngine() and ClearTransmission() methods are temporary for use by the MarketDataExtensisons class
        /// from Volpe.Cafe library. They will be removed (or made private at a class-level) after further refactoring.
        /// </summary>
        bool ClearEngine();
        /// <summary>
        /// Removes the vehicle's transmission.
        /// <br/><br/>
        /// NOTE:
        /// The ClearEngine() and ClearTransmission() methods are temporary for use by the MarketDataExtensisons class
        /// from Volpe.Cafe library. They will be removed (or made private at a class-level) after further refactoring.
        /// </summary>
        bool ClearTransmission();

    }
}
