using System; using System.Collections; using System.Linq; using System.IO; using System.Text; using System.Threading.Tasks; using Newtonsoft.Json; using schedulable; using System.Collections.Generic; using franz; using System.Threading; using System.Collections.Concurrent; namespace director { public class ShowHandler { private Scheduled todo; private string outputPath; private string checklistFilename; private Action checklistSync; private static readonly AutoResetEvent _signal = new AutoResetEvent(false); private static ConcurrentDictionary signalsReceived = new ConcurrentDictionary(); public ShowHandler(Scheduled todo, string outputPath, Action checklistSync) { this.todo = todo; this.outputPath = outputPath; this.checklistSync = checklistSync; checklistFilename = "checklist.md"; } internal void StartHandling() { Console.WriteLine($"begin the pre-pre show by creating a checklist."); initializeChecklist(); //todo: any signals one has to wait for, start listening var napLength = (todo.Showtime - todo.Configuration.LeadTimeDesired) - DateTime.Now; Console.WriteLine($"napping until {todo.Showtime - todo.Configuration.LeadTimeDesired} ({napLength})"); if (napLength.TotalMinutes > 0) { Task.WaitAll(Task.Delay(napLength)); } Console.WriteLine("nap done, begin the checklist. which to us effectively means SHOWTIME"); //or do I want to split the checklists in the config file? consider later. try { HandleChecklist(); } catch (Exception e) { HumanCommunication.Instance.Say($"error in show handler! Panicking!\n{JsonConvert.SerializeObject(e)}", HumanCommunication.LogLevel.Showstopper); } } private void initializeChecklist() { Directory.CreateDirectory(outputPath); checklistFilename = $"checklist ({todo.Occurrence._event.Summary}).md"; var invalidFilenames = System.IO.Path.GetInvalidFileNameChars().Concat(new char[] {'(', ')', ':'}); foreach (char c in invalidFilenames) { checklistFilename = checklistFilename.Replace(c, '_'); } checklistFilename = $"{outputPath}/{checklistFilename}"; Console.WriteLine($"checklistFilename: {checklistFilename}"); WriteChecklist(); } private void WriteChecklist() { var text = new StringBuilder(); text.AppendLine($"# {todo.Occurrence._event.Summary}"); foreach (var line in todo.Configuration.checklist) { if (line.type != LineType.text) { text.Append("* [ ] "); } else { text.AppendLine(); } text.AppendLine($"{line.description}"); } File.WriteAllText(checklistFilename, text.ToString()); checklistSync(); } private void markLineDone(int lineIndex, string[] fileLines) { fileLines[lineIndex] = "* [x] " + fileLines[lineIndex].Substring(6); File.WriteAllLines(checklistFilename, fileLines); this.checklistSync(); } private void HandleChecklist() { Console.WriteLine($"should now be at the desired lead time. showtime: {todo.Showtime}"); checklistSync(); while (true) { var fileLines = File.ReadAllLines(checklistFilename); var processionLineIndex = 0; var fileLineIndex = 0; foreach (var checklistLine in fileLines) { if (checklistLine.StartsWith("* [ ] ")) { break; } if (checklistLine.Length > 0 && !checklistLine.StartsWith("#")) { processionLineIndex++; } fileLineIndex++; } if (fileLineIndex > fileLines.Count() - 1) { ChecklistComplete(); return; } //file starts with a header line var targetItem = todo.Configuration.checklist.ToList()[processionLineIndex]; Console.WriteLine("consider: " + targetItem.description); switch (targetItem.type) { case LineType.manual: Console.WriteLine($"what can I do but wait? (currently {DateTime.Now.ToShortTimeString()})"); Task.WaitAll(Task.Delay(new TimeSpan(0, 5, 0))); Console.WriteLine("alright let's check."); break; case LineType.cmd: Console.WriteLine($"sending command: {targetItem.cmd} {targetItem.args}"); Telefranz.Instance.ProduceMessage(new silver_messages.directorial.execute_command() { command = targetItem.cmd, args = new List() { targetItem.args } }); Console.WriteLine("seem to have survived"); markLineDone(fileLineIndex, fileLines); break; case LineType.await_showtime: var napLength = todo.Showtime - DateTime.Now; if (napLength.TotalSeconds > 0) { Console.WriteLine("brb quick nap"); Task.WaitAll(Task.Delay(napLength)); } Console.WriteLine("actual showtime tho"); markLineDone(fileLineIndex, fileLines); break; // case LineType.await_signal: // //mark it if I have the signal, but if not, can't do anything but wait // if (signalsReceived[targetItem.cmd]) // { // markLineDone(fileLineIndex, fileLines); // } // else // { // _signal.WaitOne(new TimeSpan(0, 2, 0)); // } // break; } } } private void ChecklistComplete() { Console.WriteLine("\"another job well executed\" - lotus"); //TODO: delete folder. if necessary. Maybe. } } }