using log4net;
using skyscraper5.Mpeg2;
using skyscraper5.Skyscraper;
using skyscraper5.Skyscraper.IO;
using skyscraper5.Skyscraper.Scraper;
using skyscraper5.Skyscraper.Scraper.Storage.InMemory;
using skyscraper8.Skyscraper.Scraper.Storage;

namespace skyscraper8.GSE;

public class Pts2Bbf2 : IBbframeDeencapsulator
{
    private static readonly ILog logger = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Name);
    private readonly FileInfo _fi;
    private readonly DirectoryInfo outputDir;

    public Pts2Bbf2(FileInfo fi)
    {
        _fi = fi;
        string outputPath = Path.Combine(_fi.Directory.FullName, Path.GetFileNameWithoutExtension(_fi.Name) + "_frames");
        outputDir = new DirectoryInfo(outputPath);
        outputDir.EnsureExists();
    }

    public void Run()
    {
        TsContext mpeg2 = new TsContext();
        Stid135BbFrameReader bbFrameReader = new Stid135BbFrameReader(null, this);
        mpeg2.RegisterPacketProcessor(0x010e, bbFrameReader);
        
        SkyscraperContext context = new SkyscraperContext(mpeg2, new InMemoryScraperStorage(), new NullObjectStorage());
        context.InitalizeFilterChain();

        FileStream fileStream = _fi.OpenRead();
        context.IngestFromStream(fileStream);
    }

    private int frameNo;
    public void PushPacket(byte[] bbframe)
    {
        if (bbframe[0] != 0xb8)
        {
            return;
        }
        
        BBHeader bbHeader = new BBHeader(bbframe, 1);
        if (!bbHeader.Valid)
            return;

        string fname = String.Format("Frame{0:D8}_TSGS{1}_MIS{2:D3}_SYNC{3:D3}.bbframe", ++frameNo,bbHeader.TsGs,bbHeader.SisMis ? bbHeader.Matype2 : 0,bbHeader.SyncByte);
        
        string outfname = Path.Combine(outputDir.FullName, fname);
        ReadOnlySpan<byte> readOnlySpan = new ReadOnlySpan<byte>(bbframe, 11, bbframe.Length - 11);
        byte[] buffer = readOnlySpan.ToArray();
        File.WriteAllBytes(outfname, buffer);

        if (IpPacketFinder.TestForHttpContents(buffer))
        {
            logger.InfoFormat("Found unencrypted HTTP traffic in {0}", fname);
        }
    }
}