/// <summary>
        /// The GetPictureData.
        /// </summary>
        /// <param name="jsonBlob">The jsonBlob<see cref="Stream"/>.</param>
        /// <param name="log">The log<see cref="ILogger"/>.</param>
        /// <returns>The <see cref="QueueDataMessage"/>.</returns>
        private QueueDataMessage GetPictureData(Stream jsonBlob, ILogger log)
        {
            QueueDataMessage result = new QueueDataMessage();
            var serializer          = new JsonSerializer();

            using (StreamReader reader = new StreamReader(jsonBlob))
            {
                using (var jsonTextReader = new JsonTextReader(reader))
                {
                    result = serializer.Deserialize <QueueDataMessage>(jsonTextReader);
                }
            }

            log.LogInformation($"Successfully parsed JSON blob");
            return(result);
        }
        public async Task <IActionResult> CognitiveProcessAttendance(
            [HttpTrigger(AuthorizationLevel.Anonymous, "post", Route = "cognitive/process/attendance")]
            [RequestBodyType(typeof(QueueDataMessage), "CognitiveProcessAttendance")] HttpRequest request, ILogger log)
        {
            var validateStatus = base.AuthorizationStatus(request);

            if (validateStatus != System.Net.HttpStatusCode.Accepted)
            {
                return(new BadRequestObjectResult(validateStatus));
            }

            string           requestBody = await new StreamReader(request.Body).ReadToEndAsync();
            QueueDataMessage requestData = JsonConvert.DeserializeObject <QueueDataMessage>(requestBody);

            requestData.QueueCreateTime = DateTime.UtcNow;

            await _cognitiveService.ProcessAttendance(requestData, log);

            return(new OkObjectResult(new { message = "Process attendance successful." }));
        }
        /// <summary>
        /// The TrainStudentModel.
        /// </summary>
        /// <param name="queueDataMessage">The queueDataMessage<see cref="QueueDataMessage"/>.</param>
        /// <param name="_log">The _log<see cref="ILogger"/>.</param>
        /// <returns>The <see cref="Task"/>.</returns>
        public async Task TrainStudentModel(QueueDataMessage queueDataMessage, ILogger _log)
        {
            //Create school group
            _log.LogInformation($"TrainStudentModel: {queueDataMessage.StudentId}");
            CreateGroup(queueDataMessage.SchoolId, _log);

            var pictureURLs = new List <string>();

            try
            {
                // Define school specific student
                _log.LogInformation($"Define school specific student");
                Person student = await _faceClient.PersonGroupPerson.CreateAsync(
                    // Id of the PersonGroup that the person belonged to
                    queueDataMessage.SchoolId,
                    // studentId
                    queueDataMessage.StudentId
                    ).ConfigureAwait(false);

                BlobStorageRequest blobStorage = await _azureBlobService.GetSasUri("students");

                _log.LogInformation($"BlobStorageRequest {blobStorage.StorageUri}");

                foreach (var blobUri in queueDataMessage.PictureURLs)
                {
                    var blobUriBuilder = new System.UriBuilder($"{blobStorage.StorageUri}students/{blobUri}")
                    {
                        Query = blobStorage.StorageAccessToken
                    };
                    _log.LogInformation($"blobUriBuilder { blobUriBuilder.Uri.AbsoluteUri}");

                    try
                    {
                        await _faceClient.PersonGroupPerson.AddFaceFromUrlAsync(queueDataMessage.SchoolId, student.PersonId, blobUriBuilder.Uri.AbsoluteUri, detectionModel : DetectionModel.Detection01);

                        pictureURLs.Add(blobUri);
                        _log.LogInformation($"AddFaceFromUrlAsync Done");
                    }
                    catch (Exception ex)
                    {
                        _log.LogError(ex, $"AddFaceFromUrlAsync APIErrorException: {queueDataMessage.StudentId} URI: {blobUriBuilder.Uri.AbsoluteUri}");
                    }
                }

                _log.LogInformation($"Train the PersonGroup Start {queueDataMessage.SchoolId}");

                // Train the PersonGroup
                await _faceClient.PersonGroup.TrainAsync(queueDataMessage.SchoolId).ConfigureAwait(false);

                //while (true)
                //{
                //    Task.Delay(1000).Wait();
                //    var status = await _faceClient.LargeFaceList.GetTrainingStatusAsync(queueDataMessage.SchoolId);

                //    if (status.Status == TrainingStatusType.Running)
                //    {
                //        _log.LogInformation($"Training Running status ({queueDataMessage.StudentId}): {status.Status}");
                //        continue;
                //    }
                //    else if (status.Status == TrainingStatusType.Succeeded)
                //    {
                //        _log.LogInformation($"Training Succeeded status ({queueDataMessage.StudentId}): {status.Status}");
                //        break;
                //    }
                //}

                Task.Delay(1000).Wait();

                await _studentService.UpdateStudentProfile(queueDataMessage.StudentId, pictureURLs);

                _log.LogInformation($"Train the PersonGroup Done {queueDataMessage.SchoolId}: {queueDataMessage.StudentId}");
            }
            // Catch and display Face API errors.
            catch (APIErrorException ex)
            {
                _log.LogError(ex, $"TrainStudentModel APIErrorException: {queueDataMessage.StudentId}");
                throw new AppException("APIErrorException: ", ex.InnerException);
            }
            // Catch and display all other errors.
            catch (Exception ex)
            {
                _log.LogError(ex, $"TrainStudentModel Error: {queueDataMessage.StudentId}");
                throw new AppException("Train Student Cognitive Service Error: ", ex.InnerException);
            }
        }
        /// <summary>
        /// The ProcessAttendance.
        /// </summary>
        /// <param name="queueDataMessage">The queueDataMessage<see cref="QueueDataMessage"/>.</param>
        /// <param name="_log">The _log<see cref="ILogger"/>.</param>
        /// <returns>The <see cref="Task"/>.</returns>
        public async Task ProcessAttendance(QueueDataMessage queueDataMessage, ILogger _log)
        {
            // Call the Face API.
            try
            {
                BlobStorageRequest blobStorage = await _azureBlobService.GetSasUri("attendance");

                _log.LogInformation($"APIErrorException BlobStorageRequest: {blobStorage.StorageUri}");

                var blobUriBuilder = new System.UriBuilder($"{blobStorage.StorageUri}attendance/{queueDataMessage.PictureURLs[0]}")
                {
                    Query = blobStorage.StorageAccessToken
                };

                _log.LogInformation($"APIErrorException blobUriBuilder: {blobUriBuilder.Uri.AbsoluteUri}");


                _log.LogInformation($"Start DetectWithUrlAsync");

                IList <DetectedFace> faceList =
                    await _faceClient.Face.DetectWithUrlAsync(blobUriBuilder.Uri.AbsoluteUri, true, true, recognitionModel : "recognition_01", returnRecognitionModel : true).ConfigureAwait(false);

                _log.LogInformation($"End DetectWithUrlAsync: { faceList}");


                var detectedFaceGroups = faceList
                                         .Select((face, i) => new { DetectedFace = face.FaceId.Value, Index = i })
                                         .GroupBy(x => x.Index / 10, x => x.DetectedFace);

                List <IdentifyResult> IdentifyResults = new List <IdentifyResult>();

                foreach (var face in detectedFaceGroups)
                {
                    List <Guid?> sourceFaceIds = new List <Guid?>();

                    foreach (var detectedFace in face)
                    {
                        sourceFaceIds.Add(detectedFace);
                    }

                    var identifiedResult = await _faceClient.Face.IdentifyAsync(sourceFaceIds, queueDataMessage.SchoolId).ConfigureAwait(false);

                    IdentifyResults.AddRange(identifiedResult);
                }

                IList <string> presentStudetns = new List <string>();

                foreach (var identifyResult in IdentifyResults)
                {
                    _log.LogInformation($"identifyResult = {identifyResult}");

                    if (identifyResult.Candidates.Count() == 0)
                    {
                        _log.LogInformation($"No one identified");
                    }
                    else
                    {
                        // Get top 1 among all candidates returned
                        _log.LogInformation($"Get top 1 among all candidates returned");
                        var candidateId = identifyResult.Candidates[0].PersonId;
                        _log.LogInformation($"candidateId: {candidateId}");

                        var person = await _faceClient.PersonGroupPerson.GetAsync(queueDataMessage.SchoolId, candidateId).ConfigureAwait(false);

                        _log.LogInformation($"Identified as: {person.Name}");

                        var studentId = person.Name;
                        presentStudetns.Add(studentId);
                    }
                }

                var allStudents = await _studentService.GetAll(queueDataMessage.SchoolId, queueDataMessage.ClassId);

                foreach (var student in allStudents)
                {
                    var attaintance = new Attentdance(queueDataMessage.SchoolId, Guid.NewGuid().ToString())
                    {
                        StudentId   = student.Id,
                        ClassRoomId = queueDataMessage.ClassId,
                        TeacherId   = queueDataMessage.TeacherId,
                        CreatedBy   = queueDataMessage.TeacherId,
                        UpdatedBy   = queueDataMessage.TeacherId,
                        UpdatedOn   = DateTime.UtcNow,
                        Timestamp   = queueDataMessage.PictureTimestamp,
                        Latitude    = queueDataMessage.Latitude,
                        Longitude   = queueDataMessage.Longitude,
                        Present     = presentStudetns.Contains(student.Id)
                    };
                    _log.LogInformation($"Attentdance AddAsync: {attaintance}");

                    await _tableStorage.AddAsync("Attentdance", attaintance);

                    _log.LogInformation($"Done Attentdance AddAsync: {attaintance}");
                }
                _log.LogInformation($"Done Attentdance..");
            }
            // Catch and display Face API errors.
            catch (APIErrorException ex)
            {
                _log.LogError(ex, "ProcessAttendance Exception");

                throw new AppException("APIErrorException: ", ex.InnerException);
            }
            // Catch and display all other errors.
            catch (Exception ex)
            {
                _log.LogError(ex, "ProcessAttendance Exception");

                throw new AppException("Process Attendance Cognitive Service Error: ", ex.InnerException);
            }
        }