using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using Aitex.Common.Util;
using Aitex.Core.RT.Log;
using Aitex.Core.RT.SCCore;
using Aitex.Core.Util;
using Ionic.Zip;

namespace MECF.Framework.Common.Log
{
	public class LogCleaner
	{
		private PeriodicJob _threadDeleteLogs;

		private int _logsSaveDays = 60;

		private int _singleFileMaxSize = 100;

		public bool IsEnableCompressLogFileFunc { get; set; }

		public int LogsSaveDays
		{
			get
			{
				return (_logsSaveDays < 7) ? 7 : _logsSaveDays;
			}
			set
			{
				_logsSaveDays = value;
			}
		}

		public int SingleLogFileMaxSize
		{
			get
			{
				return (_singleFileMaxSize < 1) ? 1 : _singleFileMaxSize;
			}
			set
			{
				_singleFileMaxSize = value;
			}
		}

		public LogCleaner()
		{
			if (SC.ContainsItem("System.LogsSaveDays"))
			{
				LogsSaveDays = SC.GetValue<int>("System.LogsSaveDays");
			}
			if (SC.ContainsItem("System.IsEnableCompressLogFileFunc"))
			{
				IsEnableCompressLogFileFunc = SC.GetValue<bool>("System.IsEnableCompressLogFileFunc");
			}
			if (SC.ContainsItem("System.SingleLogFileMaxSize"))
			{
				SingleLogFileMaxSize = SC.GetValue<int>("System.SingleLogFileMaxSize");
			}
		}

		public LogCleaner(int logsSaveDays, bool isEnableCompressLogFileFunc, int singleLogFileMaxSize)
		{
			LogsSaveDays = logsSaveDays;
			IsEnableCompressLogFileFunc = isEnableCompressLogFileFunc;
			SingleLogFileMaxSize = singleLogFileMaxSize;
		}

		public LogCleaner(int logsSaveDays)
		{
			LogsSaveDays = logsSaveDays;
		}

		public void Run()
		{
			_threadDeleteLogs = new PeriodicJob(86400000, OnDeleteLog, "DeleteLog Thread", isStartNow: true);
		}

		private bool OnDeleteLog()
		{
			try
			{
				string logDir = PathManager.GetLogDir();
				DirectoryInfo directoryInfo = new DirectoryInfo(logDir);
				FileInfo[] files = directoryInfo.GetFiles();
				FileInfo[] array = files;
				foreach (FileInfo fileInfo in array)
				{
					if (fileInfo.Name.Contains("log") || fileInfo.Extension == ".log")
					{
						DateTime dateTime = DateTime.Parse(fileInfo.LastWriteTime.ToShortDateString());
						DateTime dateTime2 = DateTime.Now.AddDays(-LogsSaveDays);
						if (dateTime < dateTime2)
						{
							File.Delete(fileInfo.FullName);
							LOG.Write($"delete log successfully，logName:{fileInfo.Name}");
						}
						else if (IsEnableCompressLogFileFunc && fileInfo.Length > SingleLogFileMaxSize * 1024 * 1024 && dateTime < DateTime.Now.AddDays(-1.0) && fileInfo.Extension != ".zip" && CompressFile(fileInfo.FullName, fileInfo.FullName + ".zip"))
						{
							File.Delete(fileInfo.FullName);
							LOG.Write($"delete log successfully，logName:{fileInfo.Name}");
						}
					}
				}
			}
			catch (Exception ex)
			{
				LOG.Write(ex);
			}
			return true;
		}

		public void Stop()
		{
			_threadDeleteLogs?.Stop();
		}

		private bool CompressFile(string filePath, string zipPath, string password = "", List<string> filterExtenList = null)
		{
			try
			{
				using ZipFile zipFile = new ZipFile(Encoding.UTF8);
				if (!string.IsNullOrWhiteSpace(password))
				{
					zipFile.Password = password;
				}
				if (Directory.Exists(filePath))
				{
					if (filterExtenList == null)
					{
						zipFile.AddDirectory(filePath);
					}
					else
					{
						AddDirectory(zipFile, filePath, filePath, filterExtenList);
					}
				}
				else if (File.Exists(filePath))
				{
					zipFile.AddFile(filePath, "");
				}
				zipFile.Save(zipPath);
				return true;
			}
			catch (Exception ex)
			{
				LOG.Write(ex);
			}
			return false;
		}

		private void AddDirectory(ZipFile zip, string dirPath, string rootPath, List<string> filterExtenList)
		{
			string[] files = Directory.GetFiles(dirPath);
			int i;
			for (i = 0; i < files.Length; i++)
			{
				if (filterExtenList == null || (filterExtenList != null && !filterExtenList.Any((string d) => Path.GetExtension(files[i]).ToLower() == d.ToLower())))
				{
					string directoryPathInArchive = Path.GetFullPath(dirPath).Replace(Path.GetFullPath(rootPath), "");
					zip.AddFile(files[i], directoryPathInArchive);
				}
			}
			string[] directories = Directory.GetDirectories(dirPath);
			for (int j = 0; j < directories.Length; j++)
			{
				AddDirectory(zip, directories[j], rootPath, filterExtenList);
			}
		}

		~LogCleaner()
		{
			Stop();
		}
	}
}
