using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using skyscraper5.Dvb.DataBroadcasting;
using skyscraper5.Ietf.Rfc2460;
using skyscraper5.Ietf.Rfc971;
using skyscraper5.Mpeg2;
using skyscraper5.Skyscraper.Plugins;

namespace skyscraper5.Skyscraper.Scraper.StreamAutodetection.Contestants
{
	[SkyscraperPlugin]
	internal class MpeContestant : Contestant, IMultiprotocolEncapsulationEventHandler
    {
        public MpeContestant(int pid) 
            : base("Multiprotocol Encapsulation", pid)
        {
            PacketProcessor = new PsiDecoder(pid, new MultiprotocolEncapsulationDecoder(this));
        }

        public override void Dispose()
        {
        }

        public override void DeclareWinner(SkyscraperContext skyscraperContext, int pid, ProgramContext programContext)
        {
			skyscraperContext.DvbContext.RegisterPacketProcessor(pid, new PsiDecoder(pid, new MultiprotocolEncapsulationDecoder(skyscraperContext)));
		}

        public override void Introduce(ProgramContext programContext)
        {
	        
        }

        public void OnIpv4PacketArrival(InternetHeader internetHeader, byte[] ipv4Packet)
        {
            Score++;
        }

        public void OnIpDatagram(int sourcePid, byte[] payload)
        {
            int ipVersion = (payload[0] & 0xf0) >> 4;
            if (ipVersion == 4)
            {
                int ihl = (payload[0] & 0x0f);
                if (ihl == 0)
                {
                    Score--;
                    return;
                }
                ihl *= 32;
                ihl /= 8;
                byte[] ipv4Header = new byte[ihl];
                Array.Copy(payload, 0, ipv4Header, 0, ihl);
                InternetHeader internetHeader = new InternetHeader(ipv4Header);
                int testLength = payload.Length - ihl;
                if (payload.Length != internetHeader.TotalLength)
                {
                    Score--;
                    return;
                }

                byte[] ipv4Packet = new byte[testLength];
                Array.Copy(payload, ihl, ipv4Packet, 0, testLength);
                OnIpv4PacketArrival(internetHeader, ipv4Packet);
            }
            else if (ipVersion == 6)
            {
                Ipv6Header ipv6Header = new Ipv6Header(payload);
                if (!ipv6Header.Valid)
                {
                    Score--;
                    return;
                }

                int testLength = ipv6Header.PayloadLength + 40;
                if (payload.Length != testLength)
                {
                    Score--;
                    return;
                }
                throw new NotSupportedException("IPv6");
            }
        }
    }
}
