using Microsoft.IO;
using System;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Threading;
namespace Kingo.ThreadManager
{
    public delegate void ProcessHandler(object setp);
    public class CustomProcess
    {
        private static readonly RecyclableMemoryStreamManager streamManager = new RecyclableMemoryStreamManager();
        private static readonly byte[] end = new byte[] { 69, 78, 68, 33, 10 };
        public ProcessHandler ProcessCallback;
        private Process process;
        public CustomProcess(string pExePath)
        {
            ProcessStartInfo startInfo = new ProcessStartInfo()
            {
                FileName = pExePath,
                CreateNoWindow = true,
                RedirectStandardOutput = true,
                RedirectStandardInput = true,
                UseShellExecute = false,
                StandardOutputEncoding = System.Text.Encoding.UTF8
            };
            process = Process.Start(startInfo);
        }
        /// 
        /// 程序是否已经退出
        /// 
        public bool IsExited
        {
            get { return process.HasExited; }
        }
        private object lockObj = new object();
        /// 
        /// 是否正在忙
        /// 
        public bool IsBusy { get; private set; }
        public DateTime StartTime { get; private set; } = DateTime.Now;
        byte[] buffer = new byte[1024 * 1024];
        public void ExeTask(string pParm, ProcessHandler pProcessCallback)
        {
            this.ProcessCallback = pProcessCallback;
            this.IsBusy = true;
            this.StartTime = DateTime.Now;
            try
            {
                process.StandardInput.WriteLine(pParm);
                process.StandardInput.WriteLine("TaskStart");
                using (MemoryStream memoryStream = streamManager.GetStream())
                {
                    while (!TestEnd(memoryStream))
                    {
                        int count = process.StandardOutput.BaseStream.Read(buffer, 0, buffer.Length);
                        memoryStream.Write(buffer, 0, count);
                        //lock (lockObj)
                        //{
                        var content = memoryStream.ToArray();
                        var realLength = content.Length;
                        //处理头部
                        int headerEndIndex = 0;
                        int sIdx = -1;
                        int tIdx = -1;
                        for (int i = 0; i < realLength; i++)
                        {
                            int j = 0;
                            if (i > 0)
                                j = i - 1;
                            if (content[i] == (byte)91)
                            {
                                sIdx = i;
                            }
                            if (content[i] == (byte)93)
                            {
                                tIdx = i;
                            }
                            //if (content[i] == (byte)35 && content[j] == (byte)35)
                            //{
                            //    sIdx = tIdx;
                            //    tIdx = i;
                            //    //break;
                            //}
                        }
                        if (sIdx != -1 && tIdx != -1)
                        {
                            var contenttye2 = System.Text.Encoding.UTF8.GetString(content, 0, content.Length);
                            var contenttye = System.Text.Encoding.UTF8.GetString(content, sIdx + 1, tIdx - sIdx - 1);
                            ProcessCallback?.Invoke(contenttye);
                            Thread.Sleep(1000);
                        }
                        //}
                    }
                    {
                        var content = memoryStream.ToArray();
                        var realLength = content.Length - end.Length;
                        //处理头部
                        int headerEndIndex = 0;
                        for (int i = 0; i < realLength; i++)
                        {
                            if (content[i] == (byte)10)
                            {
                                headerEndIndex = i;
                                //break;
                            }
                        }
                        var contenttye = System.Text.Encoding.UTF8.GetString(content, headerEndIndex + 1, realLength - headerEndIndex - 1);
                    }
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
            finally
            {
                IsBusy = false;
            }
        }
        private bool TestEnd(MemoryStream memoryStream)
        {
            if (memoryStream.Length == 0)
                return false;
            byte[] endBuffer = new byte[end.Length];
            memoryStream.Seek(-end.Length, SeekOrigin.End);// = memoryStream.Length - end.Length;
            memoryStream.Read(endBuffer, 0, endBuffer.Length);
            if (endBuffer.SequenceEqual(end))
            {
                //memoryStream.SetLength(memoryStream.Length - end.Length);
                return true;
            }
            return false;
        }
        /// 
        /// 退出程序,杀掉进程
        /// 
        public void Exit()
        {
            if (!process.HasExited)
            {
                process.Kill();
            }
        }
    }
}