private void SendStatusNotification(Signal signal)
 {
     SignalReply reply = ProcessSignal(signal);
 }
        public SignalReply ProcessSignal(Signal request)
        {
            bool        isActionable = false;
            SignalReply reply        = new SignalReply();

            reply.StatusCode = StatusCode.Success;
            reply.Time       = DateTime.UtcNow;
            reply.StatusCode = StatusCode.Success;

            Signal signal = request;

            if (signal.HasTemplate)
            {
                signal = signal.GetTemplate(DbEngine);
                if (!String.IsNullOrWhiteSpace(request.ReporterId))
                {
                    signal.ReporterId = request.ReporterId;
                }
                if (!String.IsNullOrWhiteSpace(request.RouterId))
                {
                    signal.RouterId = request.RouterId;
                }
                if (!String.IsNullOrWhiteSpace(request.RouterType))
                {
                    signal.RouterType = request.RouterType;
                }
            }

            string           reporterId = Utils.GetValue(signal.ReporterId, "DefaultReporterId", "_default");
            ReporterDbRecord reporter   = DbEngine.Get <ReporterDbRecord>(reporterId);
            RouterDbRecord   router     = RouterDbRecord.Get(DbEngine, signal.RouterId, signal.RouterType, reporterId);

            if (reporter == null)
            {
                throw new Exception($"Reporter [{reporterId}] Does Not Exist.");
            }
            if (reporter.IsActive == false)
            {
                throw new Exception($"Reporter [{reporterId}] Is Not Active.");
            }
            reporter.LoadChannels(DbEngine, router);

            // Retrieve Any CueOption Templates Specified
            if (signal.Cues != null)
            {
                List <string> keys = new List <string>(signal.Cues.Keys);
                foreach (string key in keys)
                {
                    if (signal.Cues[key].HasTemplate)
                    {
                        signal.Cues[key] = signal.Cues[key].GetTemplate(DbEngine);
                    }

                    if (signal.Cues[key].Actions.Count > 0)
                    {
                        isActionable = true;
                    }
                }
            }

            SignalDbRecord signalDb = CreateSignalDbRecord();

            reply.Id          = signalDb.Id;
            signalDb.Status   = StatusType.New;
            signalDb.Time     = DateTime.UtcNow;
            signalDb.Signal   = signal;
            signalDb.IsActive = true;
            DbEngine.Update(signalDb);

            int channelCount = 0;
            int errorCount   = 0;

            foreach (string key in reporter.Channels.Keys)
            {
                ChannelDbRecord channel = reporter.Channels[key];
                SignalStatus    status;
                if (channel != null)
                {
                    if (channel.HasTemplate)
                    {
                        channel = channel.GetTemplate(DbEngine);
                    }

                    status           = SendToChannel(channel, signalDb);
                    status.ChannelId = key;
                }
                else
                {
                    status           = new SignalStatus();
                    status.ChannelId = key;
                    status.Code      = StatusCode.Failure;
                    status.Message   = $"Channel [{key}] Not Found.";
                }

                channelCount++;
                reply.Results.Add(status);
                if (status.Code == StatusCode.Failure)
                {
                    errorCount++;
                }
            }

            if (errorCount > 0)
            {
                if (errorCount == channelCount)
                {
                    reply.StatusCode = StatusCode.Failure;
                }
                else
                {
                    reply.StatusCode = StatusCode.SuccessWithErrors;
                }
            }

            if (isActionable)
            {
                signalDb.Status = StatusType.Sent;
            }
            else
            {
                signalDb.Status = StatusType.Completed;
            }
            signalDb.AddTrace(reply);
            DbEngine.Update(signalDb);

            return(reply);
        }