using DeepDrftContent.Constants; using DeepDrftContent.FileDatabase.Services; using DeepDrftContent.FileDatabase.Models; using DeepDrftContent.Processors; using DeepDrftModels.Entities; namespace DeepDrftContent; /// /// Service for managing tracks in both SQL and FileDatabase /// public class TrackContentService { private readonly FileDatabase.Services.FileDatabase _fileDatabase; private readonly AudioProcessor _audioProcessor; public TrackContentService(FileDatabase.Services.FileDatabase fileDatabase, AudioProcessor audioProcessor) { _fileDatabase = fileDatabase; _audioProcessor = audioProcessor; } /// /// Adds a new track from a WAV file to both databases /// /// Path to the WAV file /// Name of the track /// Artist name /// Optional album name /// Optional genre /// Optional release date /// Optional original browser filename captured at upload time /// The track entity with generated ID and media path public async Task AddTrackFromWavAsync( string wavFilePath, string trackName, string artist, string? album = null, string? genre = null, DateOnly? releaseDate = null, string? originalFileName = null) { try { // Process the WAV file var audioBinary = await _audioProcessor.ProcessWavFileAsync(wavFilePath); if (audioBinary == null) { throw new InvalidOperationException("Failed to process WAV file"); } // Generate a unique track ID var trackId = Guid.NewGuid().ToString(); // Ensure tracks vault exists if (!_fileDatabase.HasVault(VaultConstants.Tracks)) { await _fileDatabase.CreateVaultAsync(VaultConstants.Tracks, MediaVaultType.Audio); } // Store the audio in FileDatabase var success = await _fileDatabase.RegisterResourceAsync(VaultConstants.Tracks, trackId, audioBinary); if (!success) { throw new InvalidOperationException("Failed to store audio in FileDatabase"); } // Create the track entity for SQL database var trackEntity = new TrackEntity { EntryKey = trackId, // FileDatabase entry ID TrackName = trackName, Artist = artist, Album = album, Genre = genre, ReleaseDate = releaseDate, OriginalFileName = originalFileName }; return trackEntity; } catch (Exception ex) when (ex is not OperationCanceledException) { Console.WriteLine($"TrackContentService.AddTrackFromWavAsync failed: {ex.Message}"); return null; } } /// /// Retrieves audio binary from FileDatabase /// /// Track ID (EntryKey) /// Audio binary or null if not found public async Task GetAudioBinaryAsync(string trackId) { return await _fileDatabase.LoadResourceAsync(VaultConstants.Tracks, trackId); } /// /// Checks if FileDatabase is available and tracks vault exists /// public bool IsFileDatabaseReady() { return _fileDatabase.HasVault(VaultConstants.Tracks); } /// /// Initializes the tracks vault if it doesn't exist /// public async Task InitializeTracksVaultAsync() { if (!_fileDatabase.HasVault(VaultConstants.Tracks)) { await _fileDatabase.CreateVaultAsync(VaultConstants.Tracks, MediaVaultType.Audio); } } }