using System;
using System.Diagnostics;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using ikvm.extensions;

namespace be.ehealth.technicalconnector.config.impl
{
    public class HttpServerFake
    {
        int Port;
        private bool debug;
        private Process proc;
        private Thread th;
        
        public static int FindFreePort()
        {
            int port = 0;
            Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            try
            {
                IPEndPoint localEP = new IPEndPoint(IPAddress.Any, 0);
                socket.Bind(localEP);
                localEP = (IPEndPoint)socket.LocalEndPoint;
                port = localEP.Port;
            }
            finally
            {
                socket.Close();
            }
            return port;
        }

        public HttpServerFake(bool debug, int Port)
        {
            this.debug = debug;
            this.Port = Port;
        }

        
        public void start()
        {
            Console.WriteLine("Starting server on port " +Port);
            var processInfo = new ProcessStartInfo
            {
                CreateNoWindow = true,
                UseShellExecute = false,
                RedirectStandardOutput = debug,
                RedirectStandardError = debug,
                FileName = "java.exe",
                Arguments = "-Dhttp.server.port=" + Port +" -jar ./connector-helpers-mockserver.jar"
            };

            proc = new Process();
            proc.StartInfo = processInfo;

            ThreadStart ths = () =>
            {
                proc.Start();
                if (debug)
                {
                    while (!proc.StandardOutput.EndOfStream)
                    {
                        var line = proc.StandardOutput.ReadLine();
                        Console.WriteLine(line);
                    }
                }
            };

            th = new Thread(ths);
            th.Start();

            waitUntilServerIsRunning();
            Console.WriteLine("HttpServerFake is UP AND RUNNING");
        }

        private void waitUntilServerIsRunning()
        {
            bool down = true;
            Stopwatch stopWatch = new Stopwatch();
            stopWatch.Start();
            while (down) 
            {
                using (TcpClient tcpClient = new TcpClient())
                {
                    try
                    {
                        tcpClient.Connect("127.0.0.1", Port);
                        down = false;
                    }
                    catch (Exception e)
                    {
                        if (stopWatch.Elapsed.Seconds > 60)
                        {
                            throw new InvalidOperationException("Servers toke more than 60 seconds to become active");
                        }
                        Thread.Sleep(1000);
                    }
                }
            }
        }

        public void stop()
        {
            th.Abort();
            proc.Kill();
        }
    }
}