using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using skyscraper5.Skyscraper.Net;

namespace skyscraper5.Dvb.DataBroadcasting.IntModel
{
    public class IpMacNotification
    {
        public IpMacNotification(Platform platform, int targetType, string targetName, Operational operational)
        {
            PlatformName = platform.Name;
            PlatformProviderName = platform.ProviderName;
            PlatformProviderNameLanguageCode = platform.ProviderNameLanguageCode;
            PlatformActionType = platform.ActionType;
            PlatformNameLanguageCode = platform.NameLanguageCode;
            PlatformId = platform.PlatformId;
            PlatformProcessingOrder = platform.ProcessingOrder;

            TargetType = targetType;
            TargetName = targetName;

            OperationalNetworkId = operational.NetworkId;
            OperationalMpeFecAlgorithm = operational.MpeFecAlgorithm;
            OperationalComponentTag = operational.ComponentTag;
            OperationalTransportStreamId = operational.TransportStreamId;
            OperationalTimeSliceFecId = operational.TimeSliceFecId;
            OperationalTimeSlicing = operational.TimeSlicing;
            OperationalOriginalNetworkId = operational.OriginalNetworkId;
            OperationalServiceId = operational.ServiceId;
            OperationalTimeSliceFrameSize = operational.TimeSliceFrameSize;
            OperationalTimeSliceMaxAverageRate = operational.TimeSliceMaxAverageRate;
            OperationalTimeSliceMaxBurstDuration = operational.TimeSliceMaxBurstDuration;
            
        }

        public byte? OperationalTimeSliceMaxBurstDuration { get; set; }

        public int? OperationalTimeSliceMaxAverageRate { get; set; }

        public int? OperationalTimeSliceFrameSize { get; set; }

        public ushort? OperationalServiceId { get; set; }

        public ushort? OperationalOriginalNetworkId { get; set; }

        public bool? OperationalTimeSlicing { get; set; }

        public int? OperationalTimeSliceFecId { get; set; }

        public ushort? OperationalTransportStreamId { get; set; }

        public byte? OperationalComponentTag { get; set; }

        public int? OperationalMpeFecAlgorithm { get; set; }

        public ushort? OperationalNetworkId { get; set; }

        public string TargetName { get; set; }

        public int TargetType { get; set; }

        public byte PlatformProcessingOrder { get; set; }

        public uint PlatformId { get; set; }

        public string PlatformNameLanguageCode { get; set; }

        public byte PlatformActionType { get; set; }

        public string PlatformProviderNameLanguageCode { get; set; }

        public string PlatformProviderName { get; set; }

        public string PlatformName { get; set; }

        public static IEnumerable<IpMacNotification> FlatMap(Platform platform, Target target, Operational operational)
        {
            int results = 0;

            if (target.AllReceivers)
            {
                yield return new IpMacNotification(platform, -1, null, operational);
                yield break;
            }

            if (target.TargetIpSlashes != null)
            {
                foreach (CidrSubnet targetTargetIpSlash in target.TargetIpSlashes)
                {
                    results++;
                    yield return new IpMacNotification(platform, 1, targetTargetIpSlash.ToString(), operational);
                }
            }

            if (results == 0)
            {
                throw new NotImplementedException("Some Targets are not implemented properly.");
            }
        }

        protected bool Equals(IpMacNotification other)
        {
            return TargetName == other.TargetName && TargetType == other.TargetType && PlatformId == other.PlatformId;
        }

        public override bool Equals(object obj)
        {
            if (ReferenceEquals(null, obj)) return false;
            if (ReferenceEquals(this, obj)) return true;
            if (obj.GetType() != this.GetType()) return false;
            return Equals((IpMacNotification)obj);
        }

        public override int GetHashCode()
        {
            return HashCode.Combine(TargetName, TargetType, PlatformId);
        }
    }
}
