using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using SabreTools.Core.Tools;
using SabreTools.DatFiles;
using SabreTools.DatItems;
using SabreTools.Hashing;
using SabreTools.IO.Logging;
namespace SabreTools.Reports.Formats
{
///
/// Textfile report format
///
public class Textfile : BaseReport
{
///
/// Represents if the output goes to console or to a file
///
protected bool _writeToConsole = false;
///
/// Create a new report from the filename
///
/// List of statistics objects to set
public Textfile(List statsList)
: base(statsList)
{
}
///
public override bool WriteToFile(string? outfile, bool baddumpCol, bool nodumpCol, bool throwOnError = false)
{
InternalStopwatch watch = new($"Writing statistics to '{outfile}");
try
{
// Try to create the output file
Stream fs = _writeToConsole ? Console.OpenStandardOutput() : File.Create(outfile ?? string.Empty);
if (fs == null)
{
_logger.Warning($"File '{outfile}' could not be created for writing! Please check to see if the file is writable");
return false;
}
StreamWriter sw = new(fs);
// Now process each of the statistics
for (int i = 0; i < _statistics.Count; i++)
{
// Get the current statistic
DatStatistics stat = _statistics[i];
// If we have a directory statistic
if (stat.IsDirectory)
{
WriteIndividual(sw, stat, baddumpCol, nodumpCol);
// If we have anything but the last value, write the separator
if (i < _statistics.Count - 1)
WriteFooterSeparator(sw);
}
// If we have a normal statistic
else
{
WriteIndividual(sw, stat, baddumpCol, nodumpCol);
}
}
sw.Dispose();
fs.Dispose();
}
catch (Exception ex) when (!throwOnError)
{
_logger.Error(ex);
return false;
}
finally
{
watch.Stop();
}
return true;
}
///
/// Write a single set of statistics
///
/// StreamWriter to write to
/// DatStatistics object to write out
/// True if baddumps should be included in output, false otherwise
/// True if nodumps should be included in output, false otherwise
private static void WriteIndividual(StreamWriter sw, DatStatistics stat, bool baddumpCol, bool nodumpCol)
{
var line = new StringBuilder();
line.AppendLine($"'{stat.DisplayName}':");
line.AppendLine($"--------------------------------------------------");
line.AppendLine($" Uncompressed size: {NumberHelper.GetBytesReadable(stat!.TotalSize)}");
line.AppendLine($" Games found: {stat.MachineCount}");
line.AppendLine($" Roms found: {stat.GetItemCount(ItemType.Rom)}");
line.AppendLine($" Disks found: {stat.GetItemCount(ItemType.Disk)}");
line.AppendLine($" Roms with CRC: {stat.GetHashCount(HashType.CRC32)}");
line.AppendLine($" Roms with MD5: {stat.GetHashCount(HashType.MD5)}");
line.AppendLine($" Roms with SHA-1: {stat.GetHashCount(HashType.SHA1)}");
line.AppendLine($" Roms with SHA-256: {stat.GetHashCount(HashType.SHA256)}");
line.AppendLine($" Roms with SHA-384: {stat.GetHashCount(HashType.SHA384)}");
line.AppendLine($" Roms with SHA-512: {stat.GetHashCount(HashType.SHA512)}");
if (baddumpCol)
line.AppendLine($" Roms with BadDump status: {stat.GetStatusCount(ItemStatus.BadDump)}");
if (nodumpCol)
line.AppendLine($" Roms with Nodump status: {stat.GetStatusCount(ItemStatus.Nodump)}");
// For spacing between DATs
line.AppendLine();
line.AppendLine();
sw.Write(line.ToString());
sw.Flush();
}
///
/// Write out the footer-separator to the stream, if any exists
///
/// StreamWriter to write to
private static void WriteFooterSeparator(StreamWriter sw)
{
sw.Write("\n");
sw.Flush();
}
}
///
/// Console report format
///
public sealed class ConsoleOutput : Textfile
{
///
/// Create a new report from the filename
///
/// List of statistics objects to set
public ConsoleOutput(List statsList) : base(statsList)
{
_writeToConsole = true;
}
}
}