using System;
using System.Collections;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Security;
using System.Reflection;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using com.hnshituo.core.webapp.vo;
using Common;
using CoreFS.CA06;

namespace MeterPlugInLibrary
{
    public class ImageCurlControl
    {
        Thread task;

        public ImageCurlControl()
        {
            Init();
        }

        private void Init()
        {
        }

        /// <summary>
        /// 启动TFP上传线程
        /// </summary>
        public void Start()
        {
            if (task == null)
            {
                task = new Thread(new ThreadStart(Doworks));
                task.Start();
            }
        }

        public void Stop()
        {
            if (task != null)
            {
                task.Abort();
                task = null;
            }
        }

        private void Doworks()
        {
            do
            {
                int waitSecs = 10000;
                int i = 0;
                try
                {
                    string sPath = AppDomain.CurrentDomain.SetupInformation.ApplicationBase + "imgShort\\";
                    i = 1;
                    string picPath = Path.Combine(sPath, "tempImg");
                    i = 2;
                    ArrayList UnZipedFiles = GetFiles(picPath, ".jpg");//tmp!
                    i = 3;
                    //ZipFiles(UnZipedFiles); //2021年3月2日不再进行图片压缩，直接存到正式文件夹formalImg中
                    i = 4;
                    //获取正式目录文件进行上传
                    ArrayList files = GetFiles(sPath + "formalImg", ".jpg");
                    i = 5;
                    UploadFiles(files);
                    i = 6;
                    //删除正式目录文件
                    if (Directory.Exists(sPath))//如果不存在就不用删
                    {
                        RemoveRedundantDir(Path.Combine(sPath, "formalImg"), 0);
                    }
                    i = 7;
                }
                catch (Exception exp)
                {
                    WriteLog("ImageControl.Doworks在" + i + "位置异常，异常信息：" + exp.Message);
                }
                finally
                {
                    Thread.Sleep(waitSecs);
                }
            } while (true);

        }

        private ArrayList GetFiles(string _dirPath, string extensionName)
        {
            ArrayList files = new ArrayList();
            if (!Directory.Exists(_dirPath)) return null;


            DirectoryInfo theFolder = new DirectoryInfo(_dirPath);

            FileInfo[] fileinfos = theFolder.GetFiles("*" + extensionName);
            if (fileinfos != null && fileinfos.Count() > 0)
            {
                foreach (FileInfo fi in fileinfos)
                {
                    files.Add(fi.FullName);
                }
            }

            DirectoryInfo[] dirInfos = theFolder.GetDirectories();
            if (dirInfos != null && dirInfos.Count() > 0)
            {
                foreach (DirectoryInfo di in dirInfos)
                {
                    files.AddRange(GetFiles(di.FullName, extensionName));
                }
            }

            return files;
        }

        // 后台刷FTP线程调用
        private void UploadFiles(ArrayList files)
        {
            string localpath = Path.GetFullPath(Path.Combine(AppDomain.CurrentDomain.SetupInformation.ApplicationBase, @"imgShort\formalImg\"));
            string lastpath = AppConfigCache.ftpPath;
            foreach (string _filepath in files)
            {
                try
                {
                    string ftpdir = Path.Combine(AppConfigCache.ftpPath, DateTime.Now.ToString("yyyy-MM-dd"));

                    //验证文件名是否合法
                    string filename = Path.GetFileName(_filepath);
                    //filename :  计量作业编号_序号.jpg   计量作业编号：计量点编号+年月日时分秒
                    MeterWorkImage ci = ParseFileName(filename, ftpdir);

                    if (ci == null) continue;

                    // 上传文件
                    UploadRequest(ftpdir, localpath + filename);


                     //存储计量数据的时候，实际上是先将计量数据及图片路径
                     MeterWorkImageService service = new MeterWorkImageService();
                    RESTfulResult<string> rm = service.doSaveWf(ci); //db.doOption<string>("MeterWorkImageService", "doSaveWf", new object[] { ci }, 1);
                    if (rm.Succeed)
                    {
                        WriteLog(string.Format("更新图片记录[{0}]：{1}", ci.actualFirstNo, filename));
                        File.Delete(_filepath);
                    }
                    else
                    {
                        WriteLog(string.Format("上传图片失败! [{0}]\n{1}", ci.actualFirstNo, filename));
                    }
                    //
                }
                catch (Exception exp)
                {
                    WriteLog(string.Format("上传图片失败! [{0}]\n{1}", _filepath, exp.Message));
                }
            }
        }

        private void RemoveRedundantDir(string _path, int deep)
        {
            DirectoryInfo theFolder = new DirectoryInfo(_path);
            DirectoryInfo[] dirInfos = theFolder.GetDirectories();
            if (dirInfos != null && dirInfos.Count() > 0)
            {
                foreach (DirectoryInfo di in dirInfos)
                {
                    RemoveRedundantDir(di.FullName, deep + 1);
                }
            }

            try
            {
                if (deep == 0) return;
                FileInfo[] fileinfos = theFolder.GetFiles();
                if (fileinfos == null || fileinfos.Count() == 0)
                {
                    DateTime dt;
                    if (DateTime.TryParseExact(theFolder.Name, "yyyy-MM-dd", CultureInfo.CurrentCulture, DateTimeStyles.AllowWhiteSpaces, out dt))
                    {
                        if (TimeSpan.FromTicks(DateTime.Today.Ticks).Subtract(TimeSpan.FromTicks(dt.Date.Ticks)).TotalDays > 1)
                        {
                            Directory.Delete(_path);
                        }
                    }
                }
            }
            catch { }
        }

        /// <summary>
        /// 验证图片名称
        /// </summary>
        /// <param name="filename">计量点编号_作业编号_序号.jpg</param>
        /// <param name="ftpdir"></param>
        /// <returns></returns>
        private MeterWorkImage ParseFileName(string filename, string ftpdir)
        {
            MeterWorkImage ci = new MeterWorkImage();
            filename = Path.GetFileName(filename);
            string[] segs = filename.Split(new char[] { '_' }, StringSplitOptions.RemoveEmptyEntries);
            if (segs == null || segs.Count() < 3)
            {
                WriteLog("文件名不符合要求! (3段命名):" + filename);
                return null;
            }

            int seq;
            //int icar_seq = 0;
            //int.TryParse(car_seq, out icar_seq);


            string[] seqs = segs[2].Split(new char[] { '.' }, StringSplitOptions.RemoveEmptyEntries);

            if (seqs == null || seqs.Count() == 0 || !int.TryParse(seqs[0], out seq))
            {
                WriteLog("文件名不符合要求! (序号不正确):" + filename);
                return null;
            }

            string fullfilename = ftpdir + "/" + filename;
            fullfilename = fullfilename.Replace("//", "/").Replace("//", "/");
            PropertyInfo pi = null;
            try
            {
                pi = ci.GetType().GetProperty(string.Format("imageFile{0}", seq));
                pi.SetValue(ci, fullfilename.Replace("/pub", ""));
            }
            catch
            {
                WriteLog("文件名不符合要求! (序号超出数据库要求):" + fullfilename);
                return null;
            }

            //ci.image_time = DateTime.ParseExact(segs[0].Substring(segs[0].Length - 14, 14), "yyyyMMddHHmmss", CultureInfo.CurrentCulture);
            ci.actualFirstNo = segs[1];
            return ci;
        }

        private static void WriteLog(string str)
        {
            try
            {
                string m_szRunPath;
                m_szRunPath = System.Environment.CurrentDirectory;
                if (System.IO.Directory.Exists(m_szRunPath + "\\log") == false)
                {
                    System.IO.Directory.CreateDirectory(m_szRunPath + "\\log");
                }
                string strDate = System.DateTime.Now.ToString("yyyyMMdd");
                string strPathFile = m_szRunPath + "\\log\\" + strDate;
                if (!Directory.Exists(strPathFile))//如果不存在就创建file文件夹
                {
                    Directory.CreateDirectory(strPathFile);
                }
                System.IO.TextWriter tw = new System.IO.StreamWriter(strPathFile + "\\FTP_image_" + strDate + ".log", true);

                tw.WriteLine(System.DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
                tw.WriteLine(str);
                tw.WriteLine("\r\n");

                tw.Close();
            }
            catch { }
        }
        private void UploadRequest(string url, string filePath)
        {
            // 时间戳，用做boundary
            string timeStamp = DateTime.Now.Ticks.ToString("x");

            //根据uri创建HttpWebRequest对象
            HttpWebRequest oWebrequest = (HttpWebRequest)WebRequest.Create(new Uri(url));

            //如果是发送HTTPS请求  
            if (url.StartsWith("https", StringComparison.OrdinalIgnoreCase))
            {
                ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(CheckValidationResult);
                ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3
                                       | SecurityProtocolType.Tls
                                       | (SecurityProtocolType)0x300 //Tls11
                                       | (SecurityProtocolType)0xC00; //Tls12

                oWebrequest = WebRequest.Create(url) as HttpWebRequest;
                oWebrequest.ProtocolVersion = HttpVersion.Version11;
            }
            else
            {
                oWebrequest = WebRequest.Create(url) as HttpWebRequest;
            }

            //HttpWebRequest httpReq = (HttpWebRequest)WebRequest.Create(new Uri(url));
            oWebrequest.Method = "POST";
            oWebrequest.AllowWriteStreamBuffering = false; //对发送的数据不使用缓存
            oWebrequest.Timeout = 300000;  //设置获得响应的超时时间（300秒）
            oWebrequest.ContentType = "multipart/form-data; boundary=" + timeStamp;

            //文件
            FileStream fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read);
            BinaryReader binaryReader = new BinaryReader(fileStream);

            //头信息
            string boundary = "--" + timeStamp;
            string dataFormat = boundary + "\r\nContent-Disposition: form-data; name=\"{0}\";filename=\"{1}\"\r\nContent-Type:application/octet-stream\r\n\r\n";
            string header = string.Format(dataFormat, "file", Path.GetFileName(filePath));
            byte[] postHeaderBytes = Encoding.UTF8.GetBytes(header);

            //结束边界
            byte[] boundaryBytes = Encoding.ASCII.GetBytes("\r\n--" + timeStamp + "--\r\n");

            long length = fileStream.Length + postHeaderBytes.Length + boundaryBytes.Length;

            oWebrequest.ContentLength = length;//请求内容长度

            try
            {
                //每次上传4k
                int bufferLength = 4096;
                byte[] buffer = new byte[bufferLength];

                //已上传的字节数
                long offset = 0;
                int size = binaryReader.Read(buffer, 0, bufferLength);
                Stream postStream = oWebrequest.GetRequestStream();

                //发送请求头部消息
                postStream.Write(postHeaderBytes, 0, postHeaderBytes.Length);

                while (size > 0)
                {
                    postStream.Write(buffer, 0, size);
                    offset += size;
                    size = binaryReader.Read(buffer, 0, bufferLength);
                }

                //添加尾部边界
                postStream.Write(boundaryBytes, 0, boundaryBytes.Length);
                postStream.Close();

                //获取服务器端的响应
                using (HttpWebResponse response = (HttpWebResponse)oWebrequest.GetResponse())
                {
                    Stream receiveStream = response.GetResponseStream();
                    StreamReader readStream = new StreamReader(receiveStream, Encoding.UTF8);
                    string returnValue = readStream.ReadToEnd();
                    response.Close();
                    readStream.Close();
                }
            }
            catch (Exception ex)
            {
                //Debug.WriteLine("文件传输异常： " + ex.Message);
            }
            finally
            {
                fileStream.Close();
                binaryReader.Close();
            }
        }

        private static bool CheckValidationResult(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors errors)
        {
            return true; //总是接受  
        }
    }
}
