using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using System.Threading;
using GcDevicePc.Common;

namespace GcDevicePc
{
    class FileServerClient
    {
        
        [DllImport(@"WtFileSender.dll", EntryPoint = "fnWtClientInit", CharSet = CharSet.Unicode)]
        private static extern uint fnWtClientInit(byte[] Ip, ushort wTcpPort);

        [DllImport(@"WtFileSender.dll", EntryPoint = "fnWtFileSeverInit")]
        private static extern uint fnWtFileSeverInit(ushort wTcpPort);

        [DllImport(@"WtFileSender.dll", EntryPoint = "fnWtClientClose")]
        private static extern void fnWtClientClose(uint handle);

        [DllImport(@"WtFileSender.dll", EntryPoint = "fnWtClientCopytoServer")]
        private static extern int fnWtClientCopytoServer(uint handle, byte[] lpszFileName, byte[] lpszFilePathName, byte[] lpszRemoteFilePath);

        [DllImport(@"WtFileSender.dll", EntryPoint = "fnWtClientCopyfromServer")]
        private static extern int fnWtClientCopyfromServer(uint handle, byte[] lpszFileName, byte[] lpszFilePathName, byte[] lpszRemoteFilePath);

        [DllImport(@"WtFileSender.dll", EntryPoint = "fnWtCloseCEPro")]
        private static extern int fnWtCloseCEPro(uint handle, byte[] lpszFileName);

        [DllImport(@"WtFileSender.dll", EntryPoint = "fnWtRunPro")]
        private static extern int fnWtRunPro(uint handle, byte[] lpszFileName, byte[] lpszRemoteFilePath);


        private uint hFileServerHandle;
        private byte[] bfilename;
        private byte[] bfilepath;
        private byte[] bRemoteFilePath;
        private byte[] fIP;
        private ushort wport;

        #region 文件传输接口
        public int WtClientInit(String RemoteIP, ushort port)
        {
            int bret = 1;
            try
            {
                fIP = Encoding.Unicode.GetBytes(RemoteIP);
                wport = port;
                CallWithTimeout(ClientInit, 5000);
            }
            catch (TimeoutException ex)
            {
                bret = 0;
                Log.Error(ex.Message);
                return bret;
            }
            return bret;
        }

        public int WtClientClose()
        {
            int bret = 1;
            try
            {
                CallWithTimeout(ClientClose, 5000);
            }
            catch (TimeoutException ex)
            {
                bret = 0;
                Log.Error(ex.Message);
                Thread.Sleep(2000);
                return bret;
            }
            return bret;
        }

        public int WtClientCopytoServer(String filename, String filepath, String RemoteFilePath)
        {
            int bret = 1;

            try
            {
                bfilename = Encoding.Unicode.GetBytes(filename);
                bfilepath = Encoding.Unicode.GetBytes(filepath);
                bRemoteFilePath = Encoding.Unicode.GetBytes(RemoteFilePath);
                CallWithTimeout(ClientCopytoServer, 5000);
            }
            catch (TimeoutException ex)
            {
                bret = 0;
                Log.Error(ex.Message);
                return bret;
            }

            return bret;
        }

        public int WtClientCopytoServerNoDelay(String filename, String filepath, String RemoteFilePath)
        {
            int bret = 1;

            try
            {
                bfilename = Encoding.Unicode.GetBytes(filename);
                bfilepath = Encoding.Unicode.GetBytes(filepath);
                bRemoteFilePath = Encoding.Unicode.GetBytes(RemoteFilePath);
                if (this.hFileServerHandle != 0)
                    bret = fnWtClientCopytoServer(this.hFileServerHandle, bfilename, bfilepath, bRemoteFilePath);
            }
            catch (TimeoutException ex)
            {
                bret = 0;
                Log.Error(ex.Message);
                return bret;
            }

            return bret;
        }

        public int WtClientCopyfromServer(String filename, String filepath, String RemoteFilePath)
        {
            int bret = 1;
            try
            {
                bfilename = Encoding.Unicode.GetBytes(filename);
                bfilepath = Encoding.Unicode.GetBytes(filepath);
                bRemoteFilePath = Encoding.Unicode.GetBytes(RemoteFilePath);
                CallWithTimeout(ClientCopyfromServer, 5000);
            }
            catch (TimeoutException ex)
            {
                bret = 0;
                Log.Error(ex.Message);
                return bret;
            }

            return bret;
        }

        public int WtHMICloseRro(String filename)
        {
            int bret = 0;
            try
            {
                bfilename = Encoding.Unicode.GetBytes(filename);
                if (this.hFileServerHandle != 0)
                    bret = fnWtCloseCEPro(this.hFileServerHandle, bfilename);
            }
            catch (Exception ex)
            {
                Log.Error(ex.Message);
            }

            return bret;
        }

        public int WtHMIRunPro(String filename, String RemoteFilePath)
        {
            int bret = 0;
            try
            {
                bfilename = Encoding.Unicode.GetBytes(filename);
                bRemoteFilePath = Encoding.Unicode.GetBytes(RemoteFilePath);
                if (this.hFileServerHandle != 0)
                    bret = fnWtRunPro(this.hFileServerHandle, bfilename, bRemoteFilePath);
            }
            catch (Exception ex)
            {
                Log.Error(ex.Message);
            }

            return bret;
        }
        #endregion

        #region 内部操作接口
        void ClientInit()
        {
            int bret = 0;
            try
            {
                this.hFileServerHandle = fnWtClientInit(fIP, wport);
            }
            catch (Exception ex)
            {
                Log.Error(ex.Message);
                Thread.Sleep(3000);
            }
        }

        void ClientClose()
        {
            int bret = 0;
            try
            {
                fnWtClientClose(this.hFileServerHandle);
            }
            catch (Exception ex)
            {
                Log.Error(ex.Message);
                Thread.Sleep(3000);

            }
        }

        void ClientCopytoServer()
        {
            int bret = 0;
            try
            {
                if (this.hFileServerHandle != 0)
                    bret = fnWtClientCopytoServer(this.hFileServerHandle, bfilename, bfilepath, bRemoteFilePath);
            }
            catch (Exception ex)
            {
                Thread.Sleep(3000);
                Log.Error(ex.Message);
            }
        }

        void ClientCopyfromServer()
        {
            int bret = 0;
            try
            {
                if (this.hFileServerHandle != 0)
                    bret = fnWtClientCopyfromServer(this.hFileServerHandle, bfilename, bfilepath, bRemoteFilePath);
            }
            catch (Exception ex)
            {
                Thread.Sleep(3000);
                Log.Error(ex.Message);
            }
        }

        /// <summary>
        /// 超时退出函数
        /// </summary>
        /// <param name="action">执行方法</param>
        /// <param name="timeoutMilliseconds">毫秒</param>
        void CallWithTimeout(Action action, int timeoutMilliseconds)
        {
            Thread threadToKill = null;
            Action wrappedAction = () =>
            {
                threadToKill = Thread.CurrentThread;
                action();
            };

            IAsyncResult result = wrappedAction.BeginInvoke(null, null);
            if (result.AsyncWaitHandle.WaitOne(timeoutMilliseconds))
            {
                wrappedAction.EndInvoke(result);
            }
            else
            {
                threadToKill.Abort();
                throw new TimeoutException();
            }
        }
        #endregion

    }
}
