using System; using System.Collections.Generic; using System.Linq; namespace TINK.Model.Logging { public class LoggingDirectoryManager : ILoggingDirectoryManager { /// Name of logging subdirectory. private const string LOGDIRECTORYTITLE = "Log"; /// Prevents an invalid instance to be created. private LoggingDirectoryManager() { } public LoggingDirectoryManager( Func> fileListProvider, Func directoryExistsChecker, Action directoryCreator, Action fileEraser, string logFilePath, char directorySeparatorChar, int p_iRetainedFilesCountLimit) { m_oFileListProvider = fileListProvider ?? throw new ArgumentException($"Can not instantiate {nameof(LoggingDirectoryManager)}- object. File list provider delegate can not be null."); if (directoryExistsChecker == null) { throw new ArgumentException($"Can not instantiate {nameof(LoggingDirectoryManager)}- object. Directory existence checker delegate can not be null."); } if (directoryCreator == null) { throw new ArgumentException($"Can not instantiate {nameof(LoggingDirectoryManager)}- object. Directory creator delegate can not be null."); } m_oFileEraser = fileEraser ?? throw new ArgumentException($"Can not instantiate {nameof(LoggingDirectoryManager)}- object. File eraser delegate can not be null."); if (string.IsNullOrEmpty(logFilePath)) { throw new ArgumentException($"Can not instantiate {nameof(LoggingDirectoryManager)}- object. Log file path can not be null or empty."); } if (string.IsNullOrEmpty(directorySeparatorChar.ToString())) { throw new ArgumentException($"Can not instantiate {nameof(LoggingDirectoryManager)}- object. Directory separator character can not be null or empty."); } if (p_iRetainedFilesCountLimit < 1) { throw new ArgumentException($"Can not instantiate {nameof(LoggingDirectoryManager)}- object. Count of retained log files is {p_iRetainedFilesCountLimit} but must be equal or larger one."); } DirectorySeparatorChar = directorySeparatorChar.ToString(); LogFilePath = $"{logFilePath}{DirectorySeparatorChar}{LOGDIRECTORYTITLE}"; m_iRetainedFilesCountLimit = p_iRetainedFilesCountLimit; if (string.IsNullOrEmpty(LogFileTitle)) { LogFileTitle = $"{DateTime.Now:yyyy_MM_dd_HH_mm_ss}.jsnl"; } // Create directory if direcotry does not exist. if (directoryExistsChecker(LogFilePath) == false) { try { directoryCreator(LogFilePath); } catch (Exception l_oException) { throw new FileOperationException($"Logging directory {LogFilePath} could not be created successfully.", l_oException); } } } /// Deletes files which are out of retainment scope. public void DeleteObsoleteLogs() { var l_oExceptions = new List(); var l_oSortedFileArray = m_oFileListProvider(LogFilePath).OrderByDescending(x => x).ToArray(); for (int l_iIndex = l_oSortedFileArray.Length - 1; l_iIndex >= m_iRetainedFilesCountLimit - 1; /* files remaining count must be m_iRetainedFilesCountLimit - 1 because new log file will be added afterwards */ l_iIndex--) { try { m_oFileEraser(l_oSortedFileArray[l_iIndex]); } catch (Exception l_oExpetion) { // Getting list of log files found. l_oExceptions.Add(l_oExpetion); } } if (l_oExceptions.Count <= 0) { return; } throw new AggregateException("Deleting obsolete log files failed.", l_oExceptions.ToArray()); } /// Gets all log files in logging directory. /// /// List of log files. public IList GetLogFiles() { try { return m_oFileListProvider(LogFilePath).OrderBy(x => x).ToList(); } catch (Exception l_oExpetion) { // Getting list of log files found. throw new FileOperationException("Getting list of log files failed.", l_oExpetion); } } /// Holds delegate to provide file names. private readonly Func> m_oFileListProvider; /// Holds delegate to delete files. private readonly Action m_oFileEraser; /// Holds delegate to provide file names. private int m_iRetainedFilesCountLimit; /// Holds the log file name. private string LogFileTitle { get; } /// Holds the log file name. public string LogFilePath { get; } /// Holds the directory separator character. private string DirectorySeparatorChar { get; } /// Holds the log file name. public string LogFileName { get { return $"{LogFilePath}{DirectorySeparatorChar}{LogFileTitle}"; } } } }