using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net.NetworkInformation;
using System.Text;
using System.Threading.Tasks;
using skyscraper5.Ietf.Rfc768;
using skyscraper5.Mpeg2;
using skyscraper5.Skyscraper.IO;

namespace skyscraper5.Dvb.DataBroadcasting
{
    class MultiprotocolEncapsulationDecoder : IPsiProcessor
    {
        public IMultiprotocolEncapsulationEventHandler EventHandler { get; }

        public MultiprotocolEncapsulationDecoder(IMultiprotocolEncapsulationEventHandler eventHandler)
        {
            EventHandler = eventHandler;
        }

        public void GatherPsi(PsiSection section, int sourcePid)
        {
            MemoryStream ms = new MemoryStream(section.GetDataCopy(), false);
            if (ms.Length < 12)
                return;
            byte tableId = ms.ReadUInt8();

            ushort readUInt16Be = ms.ReadUInt16BE();
            bool sectionSyntaxIndicator = (readUInt16Be & 0x8000) != 0;
            bool privateIndicator = (readUInt16Be & 0x4000) != 0;
            int sectionLength = readUInt16Be & 0x0fff;

            byte[] macAddress = new byte[6];
            macAddress[5] = ms.ReadUInt8();
            macAddress[4] = ms.ReadUInt8();

            byte readUInt8 = ms.ReadUInt8();
            int payloadScramblingControl = (readUInt8 & 0x30) >> 4;
            if (payloadScramblingControl != 0)
                return; //We don't know how to unscramble these.
            int addressScramblingControl = (readUInt8 & 0x0c) >> 2;
            bool llcSnap = (readUInt8 & 0x02) != 0;
            bool currentNextIndicator = (readUInt8 & 0x01) != 0;

            byte sectionNumber = ms.ReadUInt8();
            byte lastSectionNumber = ms.ReadUInt8();
            macAddress[3] = ms.ReadUInt8();
            macAddress[2] = ms.ReadUInt8();
            macAddress[1] = ms.ReadUInt8();
            macAddress[0] = ms.ReadUInt8();

            long length = ms.GetAvailableBytes() - 4;
            if (length <= 0)
            {
                return;
            }
            byte[] payload = ms.ReadBytes(length);
            if (llcSnap)
            {
                HandleLlcSnap(sourcePid,payload);
            }
            else
            {
                HandleIpDatagram(sourcePid,payload);
            }

        }

        private void HandleLlcSnap(int sourcePid, byte[] payload)
        {
        }
        
        private void HandleIpDatagram(int sourcePid, byte[] payload)
        {
            EventHandler.OnIpDatagram(sourcePid, payload);
        }
    }
}
