public async Task <IActionResult> Run([HttpTrigger(AuthorizationLevel.Function, "post", Route = null)] HttpRequest req, ILogger log)
        {
            log.LogInformation("Submit to DOJ requested - submit search");
            try
            {
                if (!RIPAAuthorization.ValidateUserOrAdministratorRole(req, log).ConfigureAwait(false).GetAwaiter().GetResult())
                {
                    return(new UnauthorizedResult());
                }
            }
            catch (Exception ex)
            {
                log.LogError(ex.Message);
                return(new UnauthorizedResult());
            }

            UserProfile userProfile;

            try
            {
                var objectId = await RIPAAuthorization.GetUserId(req, log);

                userProfile = (await _userProfileCosmosDbService.GetUserProfileAsync(objectId));
                if (userProfile == null)
                {
                    throw new Exception($"User profile not found for {objectId}");
                }
            }
            catch (Exception ex)
            {
                log.LogError(ex.Message);

                return(new BadRequestObjectResult("User profile was not found"));
            }

            string stopQueryString = String.Empty;

            try
            {
                StopQueryUtility stopQueryUtility = new StopQueryUtility();
                StopQuery        stopQuery        = stopQueryUtility.GetStopQuery(req);
                stopQueryString = stopQueryUtility.GetStopsQueryString(stopQuery, false);
            }
            catch (Exception ex)
            {
                log.LogError("An error occured while evaluating the stop query.", ex);
                return(new BadRequestObjectResult("An error occured while evaluating the stop query. Please try again."));
            }

            IEnumerable <Stop> stopResponse;

            try
            {
                stopResponse = await _stopCosmosDbService.GetStopsAsync(stopQueryString);
            }
            catch (Exception ex)
            {
                log.LogError(ex, "An error occurred getting stops requested.");
                return(new BadRequestObjectResult("An error occurred getting stops requested. Please try again."));
            }

            SubmissionUtilities submissionUtilities = new SubmissionUtilities(_stopCosmosDbService, _submissionCosmosDbService, _sftpService, log);
            Guid submissionId;

            if (!submissionUtilities.IsValidSFTPConnection())
            {
                return(new BadRequestObjectResult("An error occurred connecting to DOJ SFTP service."));
            }

            try
            {
                List <string> errorList = submissionUtilities.ValidateStops(stopResponse);
                if (errorList.Any())
                {
                    errorList.Add("Please adjust your filter criteria and try again.");
                    return(new BadRequestObjectResult(string.Join(Environment.NewLine, errorList)));
                }
            }
            catch (Exception ex)
            {
                log.LogError(ex, "An error occurred validating stops.");
                return(new BadRequestObjectResult("An error validating stops requested. Please try again."));
            }

            try
            {
                submissionId = await submissionUtilities.NewSubmission(stopResponse, userProfile);
            }
            catch (Exception ex)
            {
                log.LogError($"Failure Adding Submission to CosmosDb, No Records Submitted: {ex.Message}");
                return(new BadRequestObjectResult($"Failure Adding Submission to CosmosDb, No Records Submitted: {ex.Message}"));
            }

            await _submissionServiceBusService.SendServiceBusMessagesAsync(stopResponse.Select(x => new ServiceBusMessage(Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(new SubmissionMessage()
            {
                StopId = x.Id, SubmissionId = submissionId
            })))).ToList());

            return(new OkObjectResult(new { submissionId }));
        }
        public async Task <IActionResult> Run(
            [HttpTrigger(AuthorizationLevel.Function, "post", Route = null)] SubmitRequest submitRequest, HttpRequest req, ILogger log)
        {
            log.LogInformation("Submit to DOJ requested");
            try
            {
                if (!RIPAAuthorization.ValidateUserOrAdministratorRole(req, log).ConfigureAwait(false).GetAwaiter().GetResult())
                {
                    return(new UnauthorizedResult());
                }
            }
            catch (Exception ex)
            {
                log.LogError(ex.Message);
                return(new UnauthorizedResult());
            }

            UserProfile userProfile;

            try
            {
                var objectId = await RIPAAuthorization.GetUserId(req, log);

                userProfile = (await _userProfileCosmosDbService.GetUserProfileAsync(objectId));
                if (userProfile == null)
                {
                    throw new Exception($"User profile not found for {objectId}");
                }
            }
            catch (Exception ex)
            {
                log.LogError(ex.Message);

                return(new BadRequestObjectResult("User profile was not found"));
            }

            if (submitRequest?.StopIds == null || submitRequest.StopIds.Count == 0)
            {
                return(new BadRequestObjectResult("stop ids are required"));
            }

            var where = Environment.NewLine + $"WHERE c.id IN ('{string.Join("','", submitRequest.StopIds)}')";
            var order = Environment.NewLine + $"ORDER BY c.StopDateTime DESC";

            IEnumerable <Stop> stopResponse;

            try
            {
                stopResponse = await _stopCosmosDbService.GetStopsAsync($"SELECT VALUE c FROM c {where} {order}");
            }
            catch (Exception ex)
            {
                log.LogError(ex, "An error occurred getting stops requested.");
                return(new BadRequestObjectResult("An error occurred getting stops requested. Please try again."));
            }

            SubmissionUtilities submissionUtilities = new SubmissionUtilities(_stopCosmosDbService, _submissionCosmosDbService, _sftpService, log);
            Guid submissionId;

            try
            {
                List <string> errorList = submissionUtilities.ValidateStops(stopResponse);
                if (errorList.Any())
                {
                    errorList.Add("Please adjust your filter criteria and try again.");
                    return(new BadRequestObjectResult(string.Join(Environment.NewLine, errorList)));
                }
            }
            catch (Exception ex)
            {
                log.LogError(ex, "An error occurred validating stops.");
                return(new BadRequestObjectResult("An error validating stops requested. Please try again."));
            }

            try
            {
                submissionId = await submissionUtilities.NewSubmission(stopResponse, userProfile);

                foreach (var stop in stopResponse)
                {
                    stop.Status = Enum.GetName(typeof(SubmissionStatus), SubmissionStatus.Pending);
                    await _stopCosmosDbService.UpdateStopAsync(stop);
                }
            }
            catch (Exception ex)
            {
                log.LogError($"Failure Adding Submission to CosmosDb, No Records Submitted: {ex.Message}");
                return(new BadRequestObjectResult($"Failure Adding Submission to CosmosDb, No Records Submitted: {ex.Message}"));
            }

            await _serviceBusService.SendServiceBusMessagesAsync(stopResponse.Select(x => new ServiceBusMessage(Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(new SubmissionMessage()
            {
                StopId = x.Id, SubmissionId = submissionId
            })))).ToList());

            return(new OkObjectResult(new { submissionId }));
        }
        public async Task <IActionResult> Run([HttpTrigger(AuthorizationLevel.Function, "put", Route = "PutStop/{Id}")] Common.Models.Stop stop, HttpRequest req, string Id, ILogger log)
        {
            log.LogInformation($"PUT - Put Stop requested, ID: {Id}, OID: {stop.OfficerId}, DATE: {stop.Date}, TIME: {stop.Time}");

            try
            {
                if (!RIPAAuthorization.ValidateUserOrAdministratorRole(req, log).ConfigureAwait(false).GetAwaiter().GetResult())
                {
                    return(new UnauthorizedResult());
                }
            }
            catch (Exception ex)
            {
                log.LogError(ex.Message);

                return(new UnauthorizedResult());
            }

            try
            {
                var objectId = await RIPAAuthorization.GetUserId(req, log);

                stop.EditStopOfficerId = (await _userProfileCosmosDbService.GetUserProfileAsync(objectId)).OfficerId;
            }
            catch (Exception ex)
            {
                log.LogError(ex.Message);

                return(new BadRequestObjectResult("User profile was not found"));
            }

            if (string.IsNullOrEmpty(Id))
            {
                return(new BadRequestObjectResult("Stop Id cannot be empty or null"));
            }

            if (stop.OfficerId.Length != 9)
            {
                return(new BadRequestObjectResult("Officer ID must be 9 char"));
            }

            if (stop.Location.City == null)
            {
                return(new BadRequestObjectResult("City is required"));
            }

            if (stop.Status == null)
            {
                stop.Status = SubmissionStatus.Unsubmitted.ToString();
            }

            stop.Ori = Environment.GetEnvironmentVariable("ORI"); //What is an Originating Agency Identification (ORI) Number? A nine-character identifier assigned to an agency. Agencies must identify their ORI Number...

            bool isDuplicate = await _stopCosmosDbService.CheckForDuplicateStop(stop.Id, stop.Ori, stop.OfficerId, stop.Date, stop.Time);

            if (isDuplicate)
            {
                log.LogError($"This appears to be a duplicate Stop: ID: {Id}, SID: {stop.Id}, OID: {stop.OfficerId}, DATE: {stop.Date}, TIME: {stop.Time}");

                return(new BadRequestObjectResult("This appears to be a duplicate Stop"));
            }

            stop.IsEdited = Id == "0" ? false : true;

            try
            {
                if (Id != "0")
                {
                    //Protect the submission history
                    Common.Models.Stop editingStop = await _stopCosmosDbService.GetStopAsync(Id);

                    editingStop.Id = $"{stop.Id}-{DateTime.UtcNow:yyyyMMddHHmmss}";
                    await _stopAuditCosmosDbService.UpdateStopAuditAsync(editingStop.Id, editingStop);

                    log.LogInformation($"Saving stop audit ID: {editingStop.Id}");
                    stop.ListSubmission = editingStop.ListSubmission;
                }
            }
            catch (Exception ex)
            {
                log.LogError($"Failed getting stop to protect submission history, ID: {Id}, SID: {stop.Id}, OID: {stop.OfficerId}, DATE: {stop.Date}, TIME: {stop.Time}");

                return(new BadRequestObjectResult("Failed getting stop submission history"));
            }

            int retryAttemps = GetRetrySetting("RetryAttemps", 3);
            int retrywait    = GetRetrySetting("RetryWait", 1000);

            while (retryAttemps > 0)
            {
                try
                {
                    stop.Id = Id;
                    if (stop.Id == "0")
                    {
                        await _stopCosmosDbService.AddStopAsync(stop);
                    }
                    else
                    {
                        if (!RIPAAuthorization.ValidateAdministratorRole(req, log).ConfigureAwait(false).GetAwaiter().GetResult())
                        {
                            return(new UnauthorizedResult());
                        }

                        await _stopCosmosDbService.UpdateStopAsync(stop);
                    }

                    log.LogInformation($"PUT - saved stop, ID: {Id}, SID: {stop.Id}, OID: {stop.OfficerId}, DATE: {stop.Date}, TIME: {stop.Time}");

                    return(new OkObjectResult(stop));
                }
                catch (Exception exception)
                {
                    log.LogError($"Failed to insert/update stop, attempt counter: {retryAttemps}, ID: {Id}, SID: {stop.Id}, OID: {stop.OfficerId}, DATE: {stop.Date}, TIME: {stop.Time}", exception.GetBaseException());
                }

                await Task.Delay(retrywait);

                retryAttemps--;
            }

            return(new BadRequestObjectResult("The maximum number of attemps to save the STOP was exceeded"));
        }