public async Task <IActionResult> PostSingleState(
            [BindRequired, FromQuery] string stateId,
            [BindRequired, FromQuery] Iri activityId,
            [BindRequired, FromQuery] Agent agent,
            [BindRequired, FromBody] byte[] body,
            [BindRequired, FromHeader(Name = "Content-Type")] string contentType,
            [FromQuery] Guid?registration       = null,
            CancellationToken cancellationToken = default)
        {
            if (!ModelState.IsValid)
            {
                return(BadRequest(ModelState));
            }

            AgentEntity storedAgent = await _mediator.Send(UpsertActorCommand.Create(agent));

            ActivityEntity activity = (ActivityEntity)await _mediator.Send(UpsertActivityCommand.Create(activityId), cancellationToken);

            ActivityStateDocument stateDocument = await _mediator.Send(new GetActivityStateQuery()
            {
                StateId      = stateId,
                ActivityId   = activityId,
                AgentId      = storedAgent.AgentId,
                Registration = registration
            }, cancellationToken);

            if (stateDocument != null)
            {
                stateDocument = await _mediator.Send(new UpdateStateDocumentCommand()
                {
                    StateId      = stateId,
                    ActivityId   = activityId,
                    AgentId      = storedAgent.AgentId,
                    Content      = body,
                    ContentType  = contentType,
                    Registration = registration
                }, cancellationToken);
            }
            else
            {
                stateDocument = await _mediator.Send(new CreateStateDocumentCommand()
                {
                    StateId      = stateId,
                    Activity     = activity,
                    Agent        = storedAgent,
                    Content      = body,
                    ContentType  = contentType,
                    Registration = registration
                }, cancellationToken);
            }

            Response.Headers.Add(HeaderNames.ETag, $"\"{stateDocument.Tag}\"");
            Response.Headers.Add(HeaderNames.LastModified, stateDocument.LastModified?.ToString("o"));

            return(NoContent());
        }
        public async Task <IActionResult> GetSingleState(
            [BindRequired, FromQuery] Iri activityId,
            [BindRequired, FromQuery] Agent agent,
            [FromQuery] string stateId          = null,
            [FromQuery] DateTime?since          = null,
            [FromQuery] Guid?registration       = null,
            CancellationToken cancellationToken = default)
        {
            if (!ModelState.IsValid)
            {
                return(BadRequest(ModelState));
            }

            AgentEntity agentEntity = await _mediator.Send(UpsertActorCommand.Create(agent));

            if (string.IsNullOrEmpty(stateId))
            {
                return(await GetMutipleStates(
                           activityId,
                           agentEntity.AgentId,
                           registration,
                           since,
                           cancellationToken
                           ));
            }

            ActivityStateDocument stateDocument = await _mediator.Send(new GetActivityStateQuery()
            {
                StateId      = stateId,
                ActivityId   = activityId,
                AgentId      = agentEntity.AgentId,
                Registration = registration
            }, cancellationToken);

            if (stateDocument == null)
            {
                return(NotFound());
            }

            if (Request.TryConcurrencyCheck(stateDocument.Tag, stateDocument.LastModified, out int statusCode))
            {
                return(StatusCode(statusCode));
            }

            var content = new FileContentResult(stateDocument.Content, stateDocument.ContentType.ToString())
            {
                LastModified = stateDocument.LastModified,
                EntityTag    = new EntityTagHeaderValue($"\"{stateDocument.Tag}\"")
            };

            return(content);
        }
        public async Task <IActionResult> DeleteSingleState(
            [BindRequired, FromQuery] Iri activityId,
            [BindRequired, FromQuery] Agent agent,
            [FromQuery] string stateId          = null,
            [FromQuery] Guid?registration       = null,
            CancellationToken cancellationToken = default)
        {
            if (!ModelState.IsValid)
            {
                return(BadRequest(ModelState));
            }

            var agentEntity = (await _mediator.Send(UpsertActorCommand.Create(agent)));

            if (string.IsNullOrEmpty(stateId))
            {
                await _mediator.Send(new DeleteActivityStatesCommand()
                {
                    ActivityId   = activityId,
                    AgentId      = agentEntity.AgentId,
                    Registration = registration
                }, cancellationToken);

                return(NoContent());
            }
            else
            {
                ActivityStateDocument stateDocument = await _mediator.Send(new GetActivityStateQuery()
                {
                    StateId      = stateId,
                    ActivityId   = activityId,
                    AgentId      = agentEntity.AgentId,
                    Registration = registration
                }, cancellationToken);

                if (stateDocument == null)
                {
                    return(NotFound());
                }

                await _mediator.Send(new DeleteActivityStateCommand()
                {
                    StateId      = stateId,
                    ActivityId   = activityId,
                    AgentId      = agentEntity.AgentId,
                    Registration = registration
                }, cancellationToken);
            }

            return(NoContent());
        }
        public async Task <ActionResult <StateDocumentModel> > GetSingleState(StateDocumentModel model)
        {
            if (!ModelState.IsValid)
            {
                return(BadRequest(ModelState));
            }

            try
            {
                ActivityStateDocument stateDocument = await _mediator.Send(new GetActivityStateQuery()
                {
                    StateId      = model.StateId,
                    ActivityId   = model.ActivityId,
                    Agent        = model.Agent,
                    Registration = model.Registration
                });

                if (stateDocument == null)
                {
                    return(NotFound());
                }

                if (HttpMethods.IsHead(Request.Method))
                {
                    return(NoContent());
                }

                var content = new FileContentResult(stateDocument.Content, stateDocument.ContentType.ToString());
                content.LastModified = stateDocument.LastModified;
                content.EntityTag    = new Microsoft.Net.Http.Headers.EntityTagHeaderValue(stateDocument.Tag);
                return(content);
            }
            catch (Exception ex)
            {
                return(BadRequest(ex.Message));
            }
        }
        public async Task <IActionResult> DeleteSingleState([FromQuery] StateDocumentModel model)
        {
            if (!ModelState.IsValid)
            {
                return(BadRequest(ModelState));
            }

            try
            {
                ActivityStateDocument stateDocument = await _mediator.Send(new GetActivityStateQuery()
                {
                    StateId      = model.StateId,
                    ActivityId   = model.ActivityId,
                    Agent        = model.Agent,
                    Registration = model.Registration
                });

                if (stateDocument == null)
                {
                    return(NotFound());
                }

                await _mediator.Send(new DeleteActivityStateCommand()
                {
                    StateId      = model.StateId,
                    ActivityId   = model.ActivityId,
                    Agent        = model.Agent,
                    Registration = model.Registration
                });

                return(NoContent());
            }
            catch (Exception ex)
            {
                return(BadRequest(ex));
            }
        }