using System;
using System.Collections.Concurrent;
using System.IO;
using System.Linq;
namespace StardewModdingAPI.Framework
{
/// A log writer which queues messages for output, and periodically flushes them to the console and log file.
/// Only one instance should be created.
internal class LogWriter
{
/*********
** Properties
*********/
/// The queued messages to flush.
private readonly ConcurrentQueue Queue;
/// The underlying file stream.
private readonly StreamWriter FileStream;
/*********
** Public methods
*********/
/// Construct an instance.
/// The log path to write.
public LogWriter(string path)
{
// create log directory (required for stream writer)
Directory.CreateDirectory(Path.GetDirectoryName(path));
// initialise
this.Queue = new ConcurrentQueue();
this.FileStream = new StreamWriter(Constants.LogPath, false);
}
/// Queue a message for output.
/// The message to log.
public void WriteToLog(string message)
{
lock (this.Queue)
{
var logEntry = new LogInfo(message);
this.Queue.Enqueue(logEntry);
if (this.Queue.Any())
this.FlushLog();
}
}
/// Queue a message for output.
/// The message to log.
public void WriteToLog(LogInfo message)
{
lock (this.Queue)
{
this.Queue.Enqueue(message);
if (this.Queue.Any())
this.FlushLog();
}
}
/*********
** Private methods
*********/
/// Flush the underlying queue to the console and file.
private void FlushLog()
{
lock (this.FileStream)
{
LogInfo entry;
while (this.Queue.TryDequeue(out entry))
{
string message = $"[{entry.LogTime}] {entry.Message}";
Console.ForegroundColor = entry.Colour;
Console.WriteLine(message);
Console.ForegroundColor = ConsoleColor.Gray;
this.FileStream.WriteLine(message);
}
this.FileStream.Flush();
}
}
}
}