using Common.Model;

using System;
using System.IO;
using System.Net;

namespace Common.system
{
    /// <summary>
    /// 下载方法
    /// 创建人：赵耀
    /// 创建时间：2018年10月30日
    /// </summary>
    public class DownloadService
    {
        private string downloadUrl = "";//文件下载地址
        private string filePath = "";//文件保存路径
        private string method = "";//方法
        private long fromIndex = 0;//开始下载的位置
        private long toIndex = 0;//结束下载的位置
        private long count = 0;//总大小
        private long size = 524288;//每次下载大小 512kb
        private bool isRun = false;//是否正在进行


        public bool isFinish = false;//是否已下载完成{ get; private set; }

        public bool isStopped = true;//是否已停止{ get; private set; }

        /// <summary>
        /// 开始下载
        /// </summary>
        public event Action OnStart;
        /// <summary>
        /// 下载进度
        /// </summary>
        public event Action OnDownload;
        /// <summary>
        /// 完成下载
        /// </summary>
        public event Action OnFinsh;
        /// <summary>
        /// 断开网络连接
        /// </summary>
        public event Action OnDisconnect;


        public long GetDownloadedCount()
        {
            return count - toIndex + fromIndex - 1;
        }

        public void Stop()
        {
            isRun = false;
        }

        /// <summary>
        /// 开始下载
        /// </summary>
        /// <param name="info"></param>
        /// <param name="isReStart"></param>
        /// <returns></returns>
        public bool Start(TaskInfoModel info, bool isReStart)
        {
            downloadUrl = info.downloadUrl;
            fromIndex = info.fromIndex;
            toIndex = info.toIndex;
            method = info.method;
            filePath = info.filePath;
            count = info.count;
            isStopped = false;
            if (File.Exists(filePath))
            {
                if (isReStart)
                {
                    File.Delete(filePath);
                    File.Create(filePath).Close();
                }
            }
            else
            {
                File.Create(filePath).Close();
            }
            using (FileStream file = File.Open(filePath, FileMode.Open))
            {
                fromIndex = info.fromIndex + file.Length;
            }
            if (fromIndex >= toIndex)
            {
                OnFineshHandler();
                isFinish = true;
                isStopped = true;
                return false;
            }
            OnStartHandler();
            isRun = true;
            new Action(() =>
            {
                WebResponse rsp;
                while (fromIndex < toIndex && isRun)
                {
                    long to;
                    if (fromIndex + size >= toIndex - 1)
                    {
                        to = toIndex - 1;
                    }
                    else
                    {
                        to = fromIndex + size;
                    }

                    try
                    {
                        using (rsp = HttpHelper.Download(downloadUrl, fromIndex, to, method))
                        {
                            Save(filePath, rsp.GetResponseStream());
                        }
                    }
                    catch (Exception ex)
                    {
                        string ErrMessage = "【下载】(DownloadService):" + ex.Message;
                        LogHelper.WriteErrLog(ErrMessage, ex);
                        OnDisconnectHandler();
                        return;
                    }
                }
                if (!isRun)
                {
                    isStopped = true;
                }

                if (fromIndex >= toIndex)
                {
                    isFinish = true;
                    isStopped = true;
                    OnFineshHandler();
                }

            }).BeginInvoke(null, null);
            return true;
        }
        /// <summary>
        /// 保存文件
        /// </summary>
        /// <param name="filePath"></param>
        /// <param name="stream"></param>
        private void Save(string filePath, Stream stream)
        {
            try
            {
                using (FileStream writer = File.Open(filePath, FileMode.Append))
                {
                    using (stream)
                    {
                        int repeatTimes = 0;
                        byte[] buffer = new byte[1024];
                        int length = 0;
                        while ((length = stream.Read(buffer, 0, buffer.Length)) > 0 && isRun)
                        {
                            writer.Write(buffer, 0, length);
                            fromIndex += length;
                            if (repeatTimes % 5 == 0)
                            {
                                OnDownloadHandler();
                            }
                            repeatTimes++;
                        }
                    }
                }
                OnDownloadHandler();
            }
            catch (Exception)
            {
                //异常也不影响
            }
        }
        /// <summary>
        /// 开始下载
        /// </summary>
        private void OnStartHandler()
        {
            new Action(() =>
            {
                if (OnStart != null)
                {
                    OnStart.Invoke();
                }
            }).BeginInvoke(null, null);
        }
        /// <summary>
        /// 完成下载
        /// </summary>
        private void OnFineshHandler()
        {
            new Action(() =>
            {
                if (OnFinsh != null)
                {
                    OnFinsh.Invoke();
                }

                if (OnDownload != null)
                {
                    OnDownload.Invoke();
                }
            }).BeginInvoke(null, null);
        }
        /// <summary>
        /// 下载进度
        /// </summary>
        private void OnDownloadHandler()
        {
            new Action(() =>
            {
                if (OnDownload != null)
                {
                    OnDownload.Invoke();
                }
            }).BeginInvoke(null, null);
        }
        /// <summary>
        /// 断开网络连接
        /// </summary>
        private void OnDisconnectHandler()
        {
            new Action(() =>
            {
                if (OnDisconnect != null)
                {
                    OnDisconnect.Invoke();
                }
            }).BeginInvoke(null, null);

        }
    }
}
