using System.Collections.Generic; using System.Linq; using System.Text; using System.Text.RegularExpressions; namespace FSI.Lib.Tools.RoboSharp.Results { /// /// Helper class to build a object. /// /// /// /// internal class ResultsBuilder { private ResultsBuilder() { } internal ResultsBuilder(RoboCommand roboCommand) { RoboCommand = roboCommand; Estimator = new ProgressEstimator(roboCommand); } #region < Private Members > ///Reference back to the RoboCommand that spawned this object private readonly RoboCommand RoboCommand; private readonly List outputLines = new List(); /// This is the last line that was logged. internal string LastLine => outputLines.Count > 0 ? outputLines.Last() : ""; #endregion #region < Command Options Properties > /// internal string CommandOptions { get; set; } /// internal string Source { get; set; } /// internal string Destination { get; set; } internal List RoboCopyErrors { get; } = new List(); #endregion #region < Counters in case cancellation > /// internal ProgressEstimator Estimator { get; } #endregion /// /// Add a LogLine reported by RoboCopy to the LogLines list. /// internal void AddOutput(string output) { if (output == null) return; if (Regex.IsMatch(output, @"^\s*[\d\.,]+%\s*$", RegexOptions.Compiled)) //Ignore Progress Indicators return; outputLines.Add(output); } /// /// Builds the results from parsing the logLines. /// /// /// This is used by the ProgressUpdateEventArgs to ignore the loglines when generating the estimate /// internal RoboCopyResults BuildResults(int exitCode, bool IsProgressUpdateEvent = false) { var res = Estimator.GetResults(); //Start off with the estimated results, and replace if able res.JobName = RoboCommand.Name; res.Status = new RoboCopyExitStatus(exitCode); var statisticLines = IsProgressUpdateEvent ? new List() : GetStatisticLines(); //Dir Stats if (exitCode >= 0 && statisticLines.Count >= 1) res.DirectoriesStatistic = Statistic.Parse(Statistic.StatType.Directories, statisticLines[0]); //File Stats if (exitCode >= 0 && statisticLines.Count >= 2) res.FilesStatistic = Statistic.Parse(Statistic.StatType.Files, statisticLines[1]); //Bytes if (exitCode >= 0 && statisticLines.Count >= 3) res.BytesStatistic = Statistic.Parse(Statistic.StatType.Bytes, statisticLines[2]); //Speed Stats if (exitCode >= 0 && statisticLines.Count >= 6) res.SpeedStatistic = SpeedStatistic.Parse(statisticLines[4], statisticLines[5]); res.LogLines = outputLines.ToArray(); res.RoboCopyErrors = this.RoboCopyErrors.ToArray(); res.Source = this.Source; res.Destination = this.Destination; res.CommandOptions = this.CommandOptions; return res; } private List GetStatisticLines() { var res = new List(); for (var i = outputLines.Count-1; i > 0; i--) { var line = outputLines[i]; if (line.StartsWith("-----------------------")) break; if (line.Contains(":") && !line.Contains("\\")) res.Add(line); } res.Reverse(); return res; } } }