using Renci.SshNet;
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;


namespace MeterPlugInLibrary
{
    // <summary>
    /// SFTP操作类
    /// </summary>
    public class SFTPHelper : IDisposable
    {
        #region 字段或属性
        private SftpClient sftp;
        private string cmsimagesIP;
        private int cmsimagesPort;
        private string cmsimagesName;
        private string cmsimagesPwd;

        /// <summary>
        /// SFTP连接状态
        /// </summary>
        public bool Connected { get { return sftp.IsConnected; } }
        #endregion

        #region 构造
        /// <summary>
        /// 构造
        /// </summary>
        public SFTPHelper(string _ip, int _port, string _name, string _pwd)
        {
            cmsimagesIP = _ip;
            cmsimagesPort = _port;
            cmsimagesName = _name;
            cmsimagesPwd = _pwd;
            
            WriteLog(string.Format("连接: {0} {1} {2} {3}", _ip, _port, _name, _pwd));
            sftp = new SftpClient(cmsimagesIP, cmsimagesPort, cmsimagesName, cmsimagesPwd);
        }
        #endregion

        #region 连接SFTP
        /// <summary>
        /// 连接SFTP
        /// </summary>
        /// <returns>true成功</returns>
        public bool Connect()
        {
            try
            {
                if (!Connected)
                {
                    sftp.Connect();
                    WriteLog(string.Format("连接: {0} 成功", cmsimagesIP));
                }
                return true;
            }
            catch (Exception ex)
            {
                WriteLog(string.Format("连接SFTP失败，原因：{0}", ex.Message));
            }
            return false;
        }
        #endregion

        #region 断开SFTP
        /// <summary>
        /// 断开SFTP
        /// </summary> 
        public void Disconnect()
        {
            try
            {
                if (sftp != null && Connected)
                {
                    sftp.Disconnect();
                }
            }
            catch (Exception ex)
            {
                WriteLog(string.Format("断开SFTP失败，原因：{0}", ex.Message));
            }
        }
        #endregion

        #region SFTP上传文件
        /// <summary>
        /// SFTP上传文件
        /// </summary>
        /// <param name="localPath">本地路径</param>
        /// <param name="remotePath">远程路径</param>
        /// <param name="fileName">文件名称</param>
        public int Put(string localPath, string remotePath, string fileName)
        {
            try
            {
                using (var file = File.OpenRead(localPath))
                {

                    if (!Connected) Connect();
                    //判断路径是否存在
                    if (!sftp.Exists(remotePath))
                    {
                        sftp.CreateDirectory(remotePath);
                    }
                    WriteLog(string.Format("上传文件:{0} 到 {1}", localPath, remotePath + "/" + fileName));
                    sftp.UploadFile(file, remotePath + "/" + fileName);
                    return 0;
                    // Disconnect();
                }
            }
            catch (Exception ex)
            {
                WriteLog(string.Format("SFTP文件上传失败，原因：{0}", ex.Message));
            }
            return -1;
        }
        #endregion

        #region SFTP获取文件
        /// <summary>
        /// SFTP获取文件
        /// </summary>
        /// <param name="remotePath">远程路径</param>
        /// <param name="localPath">本地路径</param>
        public string Get(string remotePath, string localPath)
        {
            try
            {
                if (!Connected) Connect();

                remotePath = remotePath.Replace(@"//", @"/");
                localPath = localPath.Replace(@"\\", @"\");

                using (var file = File.OpenWrite(localPath))
                {
                    sftp.DownloadFile(remotePath, file);
                }
                return "";
            }
            catch (Exception ex)
            {
                WriteLog(string.Format("SFTP文件获取失败，原因：{0}", ex.Message));
                return ex.Message;
            }
        }
        #endregion

        #region 获取SFTP文件列表
        /// <summary>
        /// 获取SFTP文件列表
        /// </summary>
        /// <param name="remotePath">远程目录</param>
        /// <param name="fileSuffix">文件后缀</param>
        /// <returns></returns>
        public ArrayList GetFileList(string remotePath, string fileSuffix)
        {
            try
            {
                if (!Connected) Connect();
                var files = sftp.ListDirectory(remotePath);
                //Disconnect();
                var objList = new ArrayList();
                foreach (var file in files)
                {
                    string name = file.Name;
                    if (name.Length > (fileSuffix.Length + 1) && fileSuffix == name.Substring(name.Length - fileSuffix.Length))
                    {
                        objList.Add(name);
                    }
                }
                return objList;
            }
            catch (Exception ex)
            {
                WriteLog(string.Format("SFTP文件列表获取失败，原因：{0}", ex.Message));
                return null;
            }
        }
        #endregion

        #region 移动SFTP文件
        /// <summary>
        /// 移动SFTP文件
        /// </summary>
        /// <param name="oldRemotePath">旧远程路径</param>
        /// <param name="newRemotePath">新远程路径</param>
        public void Move(string oldRemotePath, string newRemotePath)
        {
            try
            {
                if (!Connected) Connect();
                sftp.RenameFile(oldRemotePath, newRemotePath);
                // Disconnect();
            }
            catch (Exception ex)
            {
                throw new Exception(string.Format("SFTP文件移动失败，原因：{0}", ex.Message));
            }
        }
        #endregion

        #region 删除SFTP文件
        public void Delete(string remoteFile)
        {
            try
            {
                if (!Connected) Connect();
                sftp.Delete(remoteFile);
                //Disconnect();
            }
            catch (Exception ex)
            {
                WriteLog(string.Format("SFTP文件删除失败，原因：{0}", ex.Message));
            }
        }
        #endregion

        #region 创建目录
        /// <summary>
        /// 循环创建目录
        /// </summary>
        /// <param name="remotePath">远程目录</param>
        public void CreateDirectory(string remotePath)
        {
            try
            {
                if (!Connected) Connect();
                string[] paths = remotePath.Split(new char[] { '/' }, StringSplitOptions.RemoveEmptyEntries);
                string curPath = "/";
                for (int i = 0; i < paths.Length; i++)
                {
                    curPath += paths[i];
                    if (!sftp.Exists(curPath))
                    {
                        sftp.CreateDirectory(curPath);
                    }
                    if (i < paths.Length - 1)
                    {
                        curPath += "/";
                    }
                }
            }
            catch (Exception ex)
            {
                WriteLog(string.Format("创建目录失败，原因：{0}", ex.Message));
            }



        }
        #endregion


        private static void WriteLog(string str)
        {
            string m_szRunPath;
            try
            {
                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_" + 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 { }
        }

        public void Dispose()
        {
            sftp.Dispose();
            GC.SuppressFinalize(this);
        }
    }
}
