using System.Reflection;
using Microsoft.AspNetCore.Cors;
using Microsoft.AspNetCore.Mvc;
using StartupHelpers;
using Swashbuckle.AspNetCore.Annotations;
namespace Api.Controllers
{
///
/// Controller that exposes simple health and readiness endpoints for the API.
/// Routes are prefixed with "api/health".
///
[ApiController]
[Route("api/[controller]")]
// Enables only the "FrontendOnly" CORS policy so browser requests from the frontend are allowed.
[EnableCors("FrontendOnly")]
public sealed class HealthController : ControllerBase
{
///
/// Returns the deployed API version.
///
/// 200 OK with JSON payload: { "version": "1.0.0-build.20250522103045" }
// GET api/health/version
[HttpGet("version")]
[SwaggerOperation(Summary = "API version", Description = "Returns the deployed API assembly version.")]
[SwaggerResponse(StatusCodes.Status200OK, "Version returned")]
[ProducesResponseType(StatusCodes.Status200OK)]
public IActionResult Version() =>
Ok(new { version = StartupExtensions.GetApplicationVersion(Assembly.GetExecutingAssembly()) });
///
/// Liveness probe.
/// Indicates whether the process is running. Used by orchestration systems to confirm the process is alive.
///
///
/// 200 OK with JSON payload: { "status": "alive" } when the process is running.
///
// GET api/health/live
[HttpGet("live")]
[SwaggerOperation(Summary = "Liveness probe", Description = "Returns whether the API process is alive.")]
[SwaggerResponse(StatusCodes.Status200OK, "Service is alive")]
[ProducesResponseType(StatusCodes.Status200OK)]
public IActionResult Live() => Ok(new { status = "alive" });
///
/// Basic health check endpoint.
/// Returns overall status and the current server time in UTC.
///
///
/// 200 OK with JSON payload: { "status": "ok", "time": <UTC time> }.
///
// GET api/health
[HttpGet]
[SwaggerOperation(Summary = "Health check", Description = "Returns overall health status and current UTC time.")]
[SwaggerResponse(StatusCodes.Status200OK, "Health check succeeded")]
[ProducesResponseType(StatusCodes.Status200OK)]
public IActionResult Health() => Ok(new { status = "ok", time = DateTimeOffset.UtcNow });
///
/// Echo endpoint.
/// Returns the received JSON payload unchanged. Useful for testing request/response plumbing.
///
/// Arbitrary JSON from the request body. The endpoint returns the same object.
/// 200 OK with the same JSON payload provided in the request body.
// POST api/health/echo
[HttpPost("echo")]
[SwaggerOperation(Summary = "Echo payload", Description = "Returns the same JSON payload received in the request body.")]
[SwaggerResponse(StatusCodes.Status200OK, "Payload echoed successfully")]
[ProducesResponseType(StatusCodes.Status200OK)]
public IActionResult Echo(object payload) => Ok(payload);
///
/// Readiness probe.
/// Indicates whether the service is ready to accept traffic. Typically checks downstream dependencies.
///
///
/// 200 OK with JSON { "status": "ready" } when ready;
/// 503 Service Unavailable with JSON { "status": "not_ready" } when not ready.
///
// GET api/health/ready
[HttpGet("ready")]
[SwaggerOperation(Summary = "Readiness probe", Description = "Returns whether the service is ready to accept traffic.")]
[SwaggerResponse(StatusCodes.Status200OK, "Service is ready")]
[SwaggerResponse(StatusCodes.Status503ServiceUnavailable, "Service is not ready")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status503ServiceUnavailable)]
public IActionResult Ready()
{
var ready = true;
return ready
? Ok(new { status = "ready" })
: StatusCode(503, new { status = "not_ready" });
}
}
}