using System; using System.Windows; using System.ComponentModel; using System.Runtime.CompilerServices; using sharpknife.ViewModel; using System.Reflection; using System.Xml.Serialization; using System.IO; using System.Linq; using System.Threading; namespace sharpknife.Commands { [XmlInclude(typeof(AdCommand))] [XmlInclude(typeof(BalanceCommand))] [XmlInclude(typeof(ParseAdsCommand))] [XmlInclude(typeof(TestCommand))] [XmlInclude(typeof(UpdateBalanceCommand))] [XmlInclude(typeof(ClixSenseGridCommand))] public abstract class Command : ViewModelBase { public enum StatusCode { Waiting, Executing, Paused, Completed, Failed, Canceled, Expired } public bool IsExecuting { get { return (Status == StatusCode.Executing) || (Status == StatusCode.Paused); } } public bool IsCompleted { get { return (Status == StatusCode.Canceled) || (Status == StatusCode.Completed) || (Status == StatusCode.Expired) || (Status == StatusCode.Failed); } } private DateTime? firstExecuted; public DateTime? FirstExecuted { get { return firstExecuted; } set { firstExecuted = value; OnPropertyChanged("FirstExecuted"); } } private DateTime? lastExecuted; public DateTime? LastExecuted { get { return lastExecuted; } set { lastExecuted = value; OnPropertyChanged("LastExecuted"); } } private DateTime? nextExecution; public DateTime? NextExecution { get { return nextExecution; } set { nextExecution = value; OnPropertyChanged("NextExecution"); } } private StatusCode status; public StatusCode Status { get { return status; } set { status = value; OnPropertyChanged("Status"); OnPropertyChanged("IsExecuting"); } } public string Type { get { return this.GetType().Name; } } public string Group { get; set; } private string debug; public string Debug { get { return debug; } set { debug = value; OnPropertyChanged("Debug"); } } private int timeout; public int Timeout { get { return timeout; } set { timeout = value; OnPropertyChanged("Timeout"); } } public bool TimedOut { get { return LastExecuted.HasValue && DateTime.Now > LastExecuted.Value.AddSeconds(timeout); } } public Guid CommandId { get; set; } public Command() : this(DateTime.Now) { } public Command(DateTime nextExecution) { CommandId = Guid.NewGuid(); Status = StatusCode.Waiting; NextExecution = nextExecution; } public virtual void Execute() { Status = StatusCode.Executing; LastExecuted = DateTime.Now; if (firstExecuted == null) FirstExecuted = LastExecuted; Save(); } public override string ToString() { return string.Format("Status: {0} First executed: {1} Last Executed: {2} Next execution: {3}", Status, FirstExecuted, LastExecuted, NextExecution); } public virtual void Expire() { Status = StatusCode.Expired; Save(); } public virtual void Cancel() { Status = StatusCode.Canceled; Save(); } public virtual void Complete() { Status = StatusCode.Completed; Save(); } public virtual void Failed(string message) { Status = StatusCode.Failed; Debug = message; Save(); } public virtual void Restart() { Cancel(); Execute(); } public void Sleep(int seconds) { int sleep = seconds; while (sleep > 0 && !IsCompleted) { Thread.Sleep(1000); sleep--; Debug = string.Format("Sleeping {0}s", sleep); } } public void Sleep(int seconds, int minDuration) { Sleep(Math.Max(seconds, minDuration)); } public void Save() { string xml = SerializeToXML(this); using (databaseEntities context = new databaseEntities()) { CommandLog command = context.CommandLog.SingleOrDefault(c => c.CommandId == this.CommandId); if (command == null) { command = new CommandLog() { CommandLogId = Guid.NewGuid(), CommandId = this.CommandId, CreatedOn = DateTime.Now, }; context.CommandLog.AddObject((CommandLog)command); } command.ModifiedOn = DateTime.Now; command.CommandSerialization = SerializeToXML(this); command.StatusCode = (int)Status; context.SaveChanges(); } } static public string SerializeToXML(Command command) { try { XmlSerializer serializer = new XmlSerializer(typeof(Command)); StringWriter writer = new StringWriter(); serializer.Serialize(writer, command); writer.Close(); return writer.ToString(); } catch (Exception ex) { MessageBox.Show(ex.ToString()); throw ex; } } } }