#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member

using System;
using Volpe.Cafe.MarketData.Design;

using TechKey = Volpe.Cafe.TechKeys.TechKey128;

namespace Volpe.Cafe.MarketData
{
    /// <summary>
    /// Represents a revision of a product with descriptions of its engineering characteristics and/or compliance
    /// attributes for a specific model year.
    /// </summary>
    /// <seealso cref="OEMProduct{TB,TR}"/>
    /// <seealso cref="IOEMProductInfo"/>
    [Serializable]
    public class ProductRevision : IOEMProductRevision
    {
        /// <summary>
        /// Initializes a new instance of the <see cref="ProductRevision"/> class for the specified model year, using
        /// the baseline values from the specified <see cref="IOEMProduct"/>.
        /// </summary>
        /// <param name="year">The model year associated with this product revision.</param>
        /// <param name="product">
        ///     The underlying <see cref="IOEMProduct"/> associated with this component revision.
        /// </param>
        public ProductRevision(int year, IOEMProduct product)
        {
            this.RevisionYear = year;
            this.Product = product;
            this.InitializeInternal(product.BaselineInfo);
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="ProductRevision"/> class for the specified model year, using
        /// the property values from the specified <see cref="ProductRevision"/>.
        /// </summary>
        /// <param name="year">The model year associated with this product revision.</param>
        /// <param name="revision">
        ///     The product revision to use for initializing this instance. This value should represent the product's
        ///     revision for a preceding model year.
        /// </param>
        public ProductRevision(int year, IOEMProductRevision revision)
        {
            this.RevisionYear = year;
            this.Product = revision.Product;
            this.InitializeInternal(revision);
        }

        public IOEMProduct Product { get; }
        public IOEMProductInfo BaselineInfo => this.Product.BaselineInfo;

        public int RevisionYear { get; }

        public int Code => this.BaselineInfo.Code;
        public string ManufacturerName => this.BaselineInfo.ManufacturerName;

        public ModelYearKey RefreshYears => this.BaselineInfo.RefreshYears;
        public ModelYearKey RedesignYears => this.BaselineInfo.RedesignYears;

        public TechKey TechKey { get; set; }

        public void CopyFrom(IOEMProductRevision revision)
        {
            this.InitializeInternal(revision);
        }

        /// <summary>
        /// Performs additional internal initialization for the product revision, using the property values from the
        /// specified <see cref="IOEMProductInfo"/>.
        /// <br/>
        /// This method is called by the constructor at the end of initialization. Extending classes may override this
        /// method to provide additional initialization.
        /// </summary>
        protected virtual void InitializeInternal(IOEMProductInfo productInfo)
        {
            this.TechKey = productInfo.TechKey;
        }

    }
}
