using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Net.Http;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;
using ImGuiNET;
using SDL2Demo.Forms;
using skyscraper5.Skyscraper.Scraper;

namespace SDL2Demo.Jobs
{
    internal class ScrapeFromTcp : IRenderable, IJob
    {
        public ScrapeFromTcp()
        {
            isOpen = true;
            ip = "127.0.0.1";
            port = 6969;
        }
        public bool IsOpen => isOpen;
        public bool OkayButtonClicked { get; private set; }
        
        private bool isOpen;
        private string ip;
        private int port;
        private bool wantsCancellation;
        private bool allowTimeout;
        public void Render()
        {
            ImGui.Begin("Connect to TCP Stream", ref isOpen, ImGuiWindowFlags.AlwaysAutoResize);

            ImGui.InputText("IP", ref ip, 100);
            ImGui.InputInt("Port", ref port, 1, 10);
            ImGui.Checkbox("Timeout", ref allowTimeout);
            if (ImGui.Button("Connect"))
            {
                isOpen = false;
                OkayButtonClicked = true;
            }

            ImGui.End();
        }

        private JobDisplay jobDisplay;
        private ISkyscraperContext skyscraperContext;
        public void Run()
        {
            JobContext.Puppets[0].AutoMoveTo(new Point(JobContext.Puppets[0].GetHomeX(), 650));

            TcpClient tc;
            try
            {
                tc = new TcpClient(ip, port);
            }
            catch (Exception e)
            {
                JobContext.MessageQueue.Enqueue(new MessageWindow(e.Message));
                JobContext.Puppets[0].AutoMoveToHome();
                JobContext.ReadyForNextJob = true;
                return;
            }

            jobDisplay = new JobDisplay(JobContext);
            JobContext.Puppets[0].AutoMoveTo(new Point(JobContext.Puppets[0].X, 600));
            skyscraperContext = SkyscraperContextFactory.CreateSkyscraper(JobContext.DataStorage, JobContext.ObjectStorage);
            skyscraperContext.UiJunction = jobDisplay;
            skyscraperContext.TcpProxyEnabled = true;
            skyscraperContext.EnableTimeout = allowTimeout;
            skyscraperContext.TimeoutSeconds = 60;
            skyscraperContext.InitalizeFilterChain();
            BufferedStream bufferedStream = new BufferedStream(tc.GetStream(), 96256 * 2);
            JobContext.Renderables.Add(jobDisplay);
            JobContext.CanCancel = true;
            skyscraperContext.IngestFromStream(bufferedStream);
            skyscraperContext.Dispose();
            JobContext.CanCancel = false;

            tc.Close();
            tc.Dispose();
            JobContext.Puppets[0].AutoMoveToHome();
            JobContext.ReadyForNextJob = true;
        }

        public void Cancel()
        {
            JobContext.CanCancel = false;
            skyscraperContext.CancelOnNextPacket = true;
            wantsCancellation = true;
        }

        public JobContext JobContext { get; set; }
    }
}
