using System;
using System.Collections.Generic;
using CareFusion.Mosaic.Interfaces.Converters;
using CareFusion.Mosaic.Interfaces.Types.Articles;
using CareFusion.Mosaic.Interfaces.Types.Packs;

namespace CareFusion.Mosaic.Interfaces.Messages.Input
{
    /// <summary>
    /// Class which implements the InfeedInputMessage Mosaic message.
    /// </summary>
    public class InfeedInputMessage : MosaicMessage, ICloneable
    {
        #region Members

        /// <summary>
        /// List of articles that have been processed during the infeed input.
        /// </summary>
        private readonly List<RobotArticle> _articleList = new List<RobotArticle>();

        /// <summary>
        /// List of packs that have been processed during the infeed input.
        /// </summary>
        private readonly List<RobotPack> _packList = new List<RobotPack>();

        #endregion

        #region Properties

        /// <summary>
        /// Gets or sets the infeed that is used for the input.
        /// </summary>
        public int InfeedNumber { get; set; }

        /// <summary>
        /// Gets or sets an optional informational external order number.
        /// </summary>
        public string ExternalOrderNumber { get; set; }

        /// <summary>
        /// Gets or sets the status of the infeed input.
        /// </summary>
        public InfeedInputState Status { get; set; }

        /// <summary>
        /// Gets or sets the reason for the rejection of an infeed input.
        /// </summary>
        public InfeedInputRejectReason RejectReason { get; set; }

        /// <summary>
        /// Gets or sets the reason description for the rejection of an infeed input.
        /// </summary>
        public string RejectReasonText { get; set; }

        /// <summary>
        /// Gets the list of articles that were processed during the infeed input.
        /// </summary>
        public List<RobotArticle> Articles => _articleList;

        /// <summary>
        /// Gets the list of packs that were processed during the infeed input.
        /// </summary>
        public List<RobotPack> Packs => _packList;

        #endregion

        /// <summary>
        /// Initializes a new instance of the <see cref="InfeedInputMessage"/> class.
        /// </summary>
        public InfeedInputMessage()
            : base(MessageType.InfeedInputMessage)
        {
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="InfeedInputMessage"/> class.
        /// </summary>
        /// <param name="converterStream">The converter stream which created the request.</param>
        public InfeedInputMessage(IConverterStream converterStream)
            : base(MessageType.InfeedInputMessage, converterStream)
        {
        }

        /// <summary>
        /// Creates a new object that is a copy of the current instance.
        /// </summary>
        /// <returns>
        /// A new object that is a copy of this instance.
        /// </returns>
        public object Clone()
        {
            var clone = new InfeedInputMessage(this.ConverterStream);

            clone._articleList.AddRange(_articleList);
            clone._packList.AddRange(_packList);
            clone.ConverterData = this.ConverterData;
            clone.Destination = this.Destination;
            clone.ID = this.ID;
            clone.InfeedNumber = this.InfeedNumber;
            clone.ExternalOrderNumber = this.ExternalOrderNumber;
            clone.Source = this.Source;
            clone.Status = this.Status;
            clone.RejectReason = this.RejectReason;
            clone.RejectReasonText = this.RejectReasonText;
            clone.TenantID = this.TenantID;

            return clone;
        }
    }
}
