///
/// Copyright (c) 2013-2017 Sensus Metering Systems
///
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Threading;
using log4net;
using Config.Entities;
using TBF.BenchControl;
using TBF.Resources;
namespace TBF.BenchControl.Output.FileWriters.Basic
{
public class Writer : ComponentBase, IOperation, GenericDevices.IResultsWriter
{
private static readonly ILog log = LogManager.GetLogger(typeof(Writer));
public override string ToString() { return string.Format("Output.FileWriters.Basic({0})", Cfg.ToString(1)); }
readonly WriterCfg writerCfg;
readonly string separatorStr;
///
/// Result items to print
///
readonly IList rsltItems;
Results.Entities.Batch batch;
bool abort; /// Set to 'true' by Stop() operation to abort writing to the file
public Writer() {}
public Writer(Generic.IComponentCfg cfg)
: base(cfg)
{
writerCfg = cfg as WriterCfg;
switch (writerCfg.Separator)
{
default:
case Separator.None: separatorStr = string.Empty; break;
case Separator.Space: separatorStr = " "; break;
case Separator.Tabulator: separatorStr = "\t"; break;
case Separator.Comma: separatorStr = ","; break;
case Separator.Semicolon: separatorStr = ";"; break;
}
rsltItems = Results.WMeterRsltItemSpec.FromStrArray(writerCfg.SelectedItems);
log.Debug(this.ToString());
}
///
/// Returns a file name derived from a DateTime structure.
/// Creates directories on this path as a side effect.
///
/// Date and time
/// File name
string GetFilename(string destinationPath, DateTime time)
{
string directory = destinationPath; /// Ends with "\\";
switch (writerCfg.YearFolders)
{
case YearFolders.FourDigit:
directory = string.Format("{0}{1}\\", directory, time.Year.ToString("D4"));
break;
case YearFolders.TwoDigit:
directory = string.Format("{0}{1}\\", directory, (time.Year % 100).ToString("D2"));
break;
}
switch (writerCfg.MonthFolders)
{
case MonthFolders.Name:
{
string monthStr;
switch (time.Month)
{
default:
case 1: monthStr = "January"; break;
case 2: monthStr = "February"; break;
case 3: monthStr = "March"; break;
case 4: monthStr = "April"; break;
case 5: monthStr = "May"; break;
case 6: monthStr = "June"; break;
case 7: monthStr = "July"; break;
case 8: monthStr = "August"; break;
case 9: monthStr = "September"; break;
case 10: monthStr = "October"; break;
case 11: monthStr = "November"; break;
case 12: monthStr = "December"; break;
}
directory = string.Format("{0}{1}\\", directory, monthStr);
break;
}
case MonthFolders.Digit:
directory = string.Format("{0}{1}\\", directory, time.Month.ToString());
break;
case MonthFolders.TwoDigit:
directory = string.Format("{0}{1}\\", directory, time.Month.ToString("D2"));
break;
}
switch (writerCfg.DayFolders)
{
case DayFolders.Digit:
directory = string.Format("{0}{1}\\", directory, time.Day.ToString());
break;
case DayFolders.TwoDigit:
directory = string.Format("{0}{1}\\", directory, time.Day.ToString("D2"));
break;
}
Directory.CreateDirectory(directory);
try
{
if (string.IsNullOrEmpty(writerCfg.FileNameFormat)) throw new Exception();
return directory + string.Format(writerCfg.FileNameFormat, time);
}
catch
{
return string.Format("{0}{1:yyMMdd-HHmm}.txt", directory, time);
}
}
///
/// Writes the test cycle results into a file
/// Events:
/// Event.ResultsWritten
/// Event.Busy
///
/// Results to write into a file
/// Reference to the operation
public IOperation WriteResultsOp(Results.Entities.Batch batch)
{
this.batch = batch;
return this;
}
/// Start this operation
public void Start()
{
CultureInfo oriCulture = Thread.CurrentThread.CurrentCulture;
try { Thread.CurrentThread.CurrentCulture = new CultureInfo(writerCfg.Culture.ToString()); }
catch { }
WriteRslts(batch, writerCfg.DestinationPath);
WriteRslts(batch, writerCfg.DestinationPath2);
Thread.CurrentThread.CurrentCulture = oriCulture;
}
/// Run this operation
/// Event.ResultsWritten
public Event Run()
{
return Event.ResultsWritten;
}
/// Stop this operation
public void Stop()
{
}
void WriteRslts(Results.Entities.Batch batch, string destination)
{
if (batch == null || batch.WaterMeters == null || batch.WaterMeters.Count <= 0) return;
if (rsltItems == null || rsltItems.Count == 0) return;
StreamWriter writer = StreamWriter.Null;
if (!string.IsNullOrEmpty(writerCfg.DestinationPath))
{
try
{
writer = File.AppendText(GetFilename(writerCfg.DestinationPath, batch.EndTime));
}
catch
{
}
}
foreach (var wm in batch.WaterMeters)
{
if (!writerCfg.SaveGoodOnly || wm.Passed)
{
WriteWM(writer, wm);
if (abort) return;
}
}
writer.Close();
}
///
/// Write one water meter results
///
/// Water meter number (0-based)
void WriteWM(StreamWriter wr, Results.Entities.WaterMeter wm)
{
for (int i = 0; i < rsltItems.Count; i++)
{
if (abort) return;
wr.Write(rsltItems[i].Print(wm));
if (i < rsltItems.Count - 1)
{
wr.Write(separatorStr);
}
else
{
wr.WriteLine(string.Empty);
}
}
}
}
}