using System.Diagnostics;
using Microsoft.AspNetCore.Mvc;
using w4c_workflows.Filters;
using w4c_workflows.Services;
namespace w4c_workflows.Controllers;
///
/// Workflow file management endpoints. Provides CRUD operations for the
/// workflow YAML definitions and their sibling code files (shell scripts,
/// JS, Python, etc.) stored in the tenant's private Forgejo repo.
///
/// Requires the Forgejo-backed mode to be active (Forgejo:AdminToken
/// configured). In filesystem-only mode these endpoints return 503.
///
[ApiController]
[Route("api/workflow-files")]
public class WorkflowFilesController : ControllerBase
{
private readonly WorkflowSourceFactory _sourceFactory;
private readonly ILogger _logger;
public WorkflowFilesController(
WorkflowSourceFactory sourceFactory,
ILogger logger)
{
_sourceFactory = sourceFactory;
_logger = logger;
}
private string TenantId => (string?)HttpContext.Items["TenantId"]
?? throw new InvalidOperationException("TenantId not resolved by auth middleware");
///
/// The user's Forgejo login, resolved from the tenant ID by the
/// WorkflowSourceMiddleware. Used for repo path lookups since repos
/// are per-user: {login}/workflows-{login}.
///
private string ForgejoLogin => (string?)HttpContext.Items["ForgejoLogin"]
?? throw new InvalidOperationException("ForgejoLogin not resolved by WorkflowSourceMiddleware");
/// Returns the Forgejo repo info for this tenant's workflow files.
[HttpGet("repo")]
[RequireScope("read")]
public IActionResult GetRepoInfo()
{
if (_sourceFactory.Forgejo == null)
return StatusCode(503, new { error = "Forgejo-backed workflow mode is not configured." });
var login = ForgejoLogin;
var cloneDir = _sourceFactory.Forgejo.TenantCloneDir(login);
var fullName = ForgejoWorkflowRepoService.RepoFullNameForLogin(login);
var exists = Directory.Exists(Path.Combine(cloneDir, ".git"));
return Ok(new
{
repoFullName = fullName,
cloneDir,
cloned = exists,
forgejoUrl = $"{_sourceFactory.Forgejo.GetType().GetProperty("ForgejoBase")?.GetValue(_sourceFactory.Forgejo) ?? "https://forgejo.wiz4chat.com"}/{fullName}",
});
}
///
/// Lists all files in the tenant's workflow repo (recursive, excluding .git).
/// Returns relative paths and basic file info.
///
[HttpGet]
[RequireScope("read")]
public IActionResult ListFiles([FromQuery] string? path = null)
{
if (_sourceFactory.Forgejo == null)
return StatusCode(503, new { error = "Forgejo-backed workflow mode is not configured." });
var cloneDir = _sourceFactory.Forgejo.TenantCloneDir(ForgejoLogin);
if (!Directory.Exists(cloneDir))
return Ok(new { files = Array.Empty