using Microsoft.AspNetCore.Mvc; using RR3CommunityServer.Services; namespace RR3CommunityServer.Controllers; [ApiController] [Route("api/[controller]")] public class AssetManagementController : ControllerBase { private readonly AssetExtractionService _assetExtraction; private readonly ILogger _logger; private readonly string _assetBasePath; public AssetManagementController( AssetExtractionService assetExtraction, ILogger logger, IConfiguration configuration) { _assetExtraction = assetExtraction; _logger = logger; _assetBasePath = configuration["AssetBasePath"] ?? Path.Combine(Directory.GetCurrentDirectory(), "Assets"); } /// /// Extract a single .z asset file /// [HttpPost("extract")] public async Task ExtractAsset([FromBody] ExtractRequest request) { try { var filePath = Path.Combine(_assetBasePath, request.FileName); var outputPath = await _assetExtraction.ExtractZFileAsync(filePath, request.OutputPath); return Ok(new { resultCode = 0, message = "Success", data = new { inputFile = filePath, outputFile = outputPath, size = new FileInfo(outputPath).Length } }); } catch (FileNotFoundException ex) { return NotFound(new { resultCode = 404, message = ex.Message }); } catch (Exception ex) { _logger.LogError(ex, "Error extracting asset"); return StatusCode(500, new { resultCode = 500, message = ex.Message }); } } /// /// Pack a file to .z format /// [HttpPost("pack")] public async Task PackAsset([FromBody] PackRequest request) { try { var filePath = Path.Combine(_assetBasePath, request.FileName); var outputPath = await _assetExtraction.PackZFileAsync(filePath, request.OutputPath); return Ok(new { resultCode = 0, message = "Success", data = new { inputFile = filePath, outputFile = outputPath, size = new FileInfo(outputPath).Length } }); } catch (FileNotFoundException ex) { return NotFound(new { resultCode = 404, message = ex.Message }); } catch (Exception ex) { _logger.LogError(ex, "Error packing asset"); return StatusCode(500, new { resultCode = 500, message = ex.Message }); } } /// /// Batch extract all .z files in a directory /// [HttpPost("batch-extract")] public async Task BatchExtract([FromBody] BatchExtractRequest request) { try { var inputDir = Path.Combine(_assetBasePath, request.InputDirectory); var outputDir = string.IsNullOrEmpty(request.OutputDirectory) ? null : Path.Combine(_assetBasePath, request.OutputDirectory); var results = await _assetExtraction.BatchExtractAsync(inputDir, outputDir); var successful = results.Count(r => !r.Value.StartsWith("ERROR:")); var failed = results.Count - successful; return Ok(new { resultCode = 0, message = "Success", data = new { totalFiles = results.Count, successful, failed, results = results.Select(r => new { inputFile = Path.GetFileName(r.Key), outputFile = Path.GetFileName(r.Value), status = r.Value.StartsWith("ERROR:") ? "failed" : "success", error = r.Value.StartsWith("ERROR:") ? r.Value : null }) } }); } catch (DirectoryNotFoundException ex) { return NotFound(new { resultCode = 404, message = ex.Message }); } catch (Exception ex) { _logger.LogError(ex, "Error in batch extraction"); return StatusCode(500, new { resultCode = 500, message = ex.Message }); } } /// /// List all available .z assets /// [HttpGet("list")] public IActionResult ListAssets([FromQuery] string? directory = null) { try { var searchDir = string.IsNullOrEmpty(directory) ? _assetBasePath : Path.Combine(_assetBasePath, directory); if (!Directory.Exists(searchDir)) { return NotFound(new { resultCode = 404, message = "Directory not found" }); } var zFiles = Directory.GetFiles(searchDir, "*.z", SearchOption.AllDirectories) .Select(f => new { fileName = Path.GetFileName(f), relativePath = Path.GetRelativePath(_assetBasePath, f), size = new FileInfo(f).Length, modified = new FileInfo(f).LastWriteTimeUtc }) .ToList(); return Ok(new { resultCode = 0, message = "Success", data = new { directory = searchDir, fileCount = zFiles.Count, files = zFiles } }); } catch (Exception ex) { _logger.LogError(ex, "Error listing assets"); return StatusCode(500, new { resultCode = 500, message = ex.Message }); } } } public record ExtractRequest(string FileName, string? OutputPath = null); public record PackRequest(string FileName, string? OutputPath = null); public record BatchExtractRequest(string InputDirectory, string? OutputDirectory = null);