using System;
using System.IO;
using System.Reflection;
using System.Text;

namespace Siger.Middlelayer.Common.Helpers
{
    public class FileUtility
    {
        /// <summary>
        /// 传入DB中的文件路径,返回物理地址
        /// </summary>
        /// <param name="path"></param>
        /// <returns></returns>
        public static string GetTruePath(string path)
        {
            var filename = Path.GetFileName(path);
            var retName = Path.Combine(CommonConst.UploadProgramFilePath, filename);
            var pathRoot = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location);
            var result = Path.Combine(pathRoot, retName);
            return result;
        }

        /// <summary>
        /// 传入DB中的文件路径,返回物理地址 东方富力
        /// </summary>
        /// <param name="path"></param>
        /// <returns></returns>
        public static string GetTruePathFL(string path)
        {
            var filename = Path.GetFileName(path);
            var pathStr = path.Split('/');
            var filedate = "";
            if (pathStr.Length>2)
            {
                filedate = pathStr[pathStr.Length - 2].ToString();
            }
           
            var retName = Path.Combine(CommonConst.DfflProgramFilePath, filedate, filename);
            var pathRoot = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location);
            var result = Path.Combine(pathRoot, retName);
            return result;
        }

        /// <summary>
        /// 传入DB中的文件路径,返回物理地址 东方富力
        /// </summary>
        /// <param name="path"></param>
        /// <returns></returns>
        public static string GetTruePathDffl(string path)
        {
            var filename = $"AdjustmentCertificate-{DateTime.Now:yyyyMMddHHmmss}.xlsx";
            var retName = Path.Combine(CommonConst.DfflProgramFilePath, filename);
            var pathRoot = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location);
            var result = Path.Combine(pathRoot, retName);
            return result;
        }

        /// <summary>
        /// 传入DB中的文件路径,返回物理地址
        /// </summary>
        /// <param name="path"></param>
        /// <returns></returns>
        public static string GetEsopTruePath(string path)
        {
            var filename = Path.GetFileName(path);
            var retName = Path.Combine(CommonConst.EsopProgramFilePath, filename);
            var pathRoot = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location);
            var result = Path.Combine(pathRoot, retName);
            return result;
        }

        /// <summary>
        /// 传入DB中的文件路径,返回物理地址
        /// </summary>
        /// <param name="path"></param>
        /// <returns></returns>
        public static string GetAccTruePath(string path)
        {
            var filename = Path.GetFileName(path);
            var retName = Path.Combine(CommonConst.UploadLabelFilePath, filename);
            var pathRoot = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location);
            var result = Path.Combine(pathRoot, retName);
            return result;
        }

        /// <summary>
        /// 传入前端的文件路径,返回对外地址
        /// </summary>
        /// <param name="path"></param>
        /// <returns></returns>
        public static string GetDisplayPath(string path)
        {
            var filename = Path.GetFileName(path);
            var retName = Path.Combine(CommonConst.DisplayProgramFilePath, filename);
            return retName;
        }

        public static string GetFileSize(int size)
        {
            int rank = 0;
            while (size > 1024)
            {
                size /= 1024;
                rank++;
            }
            string unit = "B";
            switch (rank)
            {
                case 1:
                    unit = "KB";
                    break;
                case 2:
                    unit = "MB";
                    break;
                case 3:
                    unit = "GB";
                    break;
                case 4:
                    unit = "TB";
                    break;
            }
            return size + " " + unit;
        }

        /// <summary>
        /// 根据文件自动觉察编码并输出内容
        /// </summary>
        /// <param name="path"></param>
        /// <returns></returns>
        public static string GetText(string path)
        {
            //注册编码提供程序
            Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);

            StringBuilder result = new StringBuilder();
            //var enc = GetEncoding(path, Encoding.GetEncoding("gb2312"));
            var enc = GetEncoding(path, Encoding.Default);
            using (var sr = new StreamReader(path, enc))
            {
                result.Append(sr.ReadToEnd());
            }
            return result.ToString();
        }

        /// <summary>
        /// 根据文件尝试返回字符编码
        /// </summary>
        /// <param name="file">文件路径</param>
        /// <param name="defEnc">没有BOM返回的默认编码</param>
        /// <returns>如果文件无法读取，返回null。否则，返回根据BOM判断的编码或者缺省编码（没有BOM）。</returns>
        static Encoding GetEncoding(string file, Encoding defEnc)
        {
            using (var stream = File.OpenRead(file))
            {
                //判断流可读？
                if (!stream.CanRead)
                    return null;
                //字节数组存储BOM
                var bom = new byte[4];
                //实际读入的长度
                int readc;
                readc = stream.Read(bom, 0, 4);
                if (readc >= 2)
                {
                    if (readc >= 4)
                    {
                        //UTF32，Big-Endian
                        if (CheckBytes(bom, 4, 0x00, 0x00, 0xFE, 0xFF))
                            return new UTF32Encoding(true, true);
                        //UTF32，Little-Endian
                        if (CheckBytes(bom, 4, 0xFF, 0xFE, 0x00, 0x00))
                            return new UTF32Encoding(false, true);
                    }
                    //UTF8
                    if (readc >= 3 && CheckBytes(bom, 3, 0xEF, 0xBB, 0xBF))
                        return new UTF8Encoding(true);

                    //UTF16，Big-Endian
                    if (CheckBytes(bom, 2, 0xFE, 0xFF))
                        return new UnicodeEncoding(true, true);
                    //UTF16，Little-Endian
                    if (CheckBytes(bom, 2, 0xFF, 0xFE))
                        return new UnicodeEncoding(false, true);
                }
                return defEnc;
            }
        }

        //辅助函数，判断字节中的值
        static bool CheckBytes(byte[] bytes, int count, params int[] values)
        {
            for (int i = 0; i < count; i++)
                if (bytes[i] != values[i])
                    return false;
            return true;
        }
    }
}
