using System.IO; using UtopiaCanteenSystem.Services.Logging; namespace UtopiaCanteenSystem.Data; /// /// Central location for persistent paths (database and config). Uses LocalApplicationData /// so data survives app updates when the application is deployed from a file server. /// public static class DatabasePath { private static string? _appDataFolder; private static string? _dbPath; private static string _productFolderName = "UtopiaCanteenSystem"; private static bool _useInteractiveLocalAppData; /// /// Use "UtopiaCanteenBackend" for the Windows Service; default is legacy WPF folder name. /// public static void UseBackendServiceStorage() { _productFolderName = "UtopiaCanteenBackend"; _useInteractiveLocalAppData = true; _appDataFolder = null; _dbPath = null; } public static void UseClientStorage() { _productFolderName = "UtopiaCanteenClient"; _useInteractiveLocalAppData = false; _appDataFolder = null; _dbPath = null; } /// /// Folder under LocalApplicationData for DB and config. Created on first use. /// public static string GetAppDataFolder() { if (_appDataFolder != null) return _appDataFolder; var localAppDataRoot = ResolveLocalAppDataRoot(); _appDataFolder = Path.Combine(localAppDataRoot, _productFolderName); Directory.CreateDirectory(_appDataFolder); MigrateBackendSystemProfileStorageIfNeeded(_appDataFolder); return _appDataFolder; } private static string ResolveLocalAppDataRoot() { if (_useInteractiveLocalAppData) { var interactive = InteractiveUserPath.TryGetLocalAppDataPath(); if (!string.IsNullOrWhiteSpace(interactive)) return interactive; } return Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData); } private static void MigrateBackendSystemProfileStorageIfNeeded(string newFolder) { if (!_useInteractiveLocalAppData) return; var systemProfileFolder = Path.Combine( Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), _productFolderName); if (string.Equals(systemProfileFolder, newFolder, StringComparison.OrdinalIgnoreCase) || !Directory.Exists(systemProfileFolder)) return; var oldDbPath = Path.Combine(systemProfileFolder, "utopia_canteen.db"); var newDbPath = Path.Combine(newFolder, "utopia_canteen.db"); if (File.Exists(oldDbPath) && !File.Exists(newDbPath)) { CopyIfMissing(oldDbPath, newDbPath); CopyIfMissing(Path.Combine(systemProfileFolder, "utopia_canteen.db-wal"), Path.Combine(newFolder, "utopia_canteen.db-wal")); CopyIfMissing(Path.Combine(systemProfileFolder, "utopia_canteen.db-shm"), Path.Combine(newFolder, "utopia_canteen.db-shm")); } CopyIfMissing(Path.Combine(systemProfileFolder, "backend-settings.json"), Path.Combine(newFolder, "backend-settings.json")); } private static void CopyIfMissing(string sourcePath, string destinationPath) { if (!File.Exists(sourcePath) || File.Exists(destinationPath)) return; try { File.Copy(sourcePath, destinationPath); } catch { // If migration fails, the app will continue with files already present or create new ones. } } /// /// Full path to the SQLite database file. If a DB exists in the legacy app-directory /// location, it is copied to the new location once. /// public static string GetDbPath() { if (_dbPath != null) return _dbPath; var folder = GetAppDataFolder(); _dbPath = Path.Combine(folder, "utopia_canteen.db"); MigrateLegacyDbIfNeeded(_dbPath); return _dbPath; } /// /// Full path to appsettings.json (remember-me credentials and other config). /// Stored in the same persistent folder so it survives updates. If a config exists /// in the legacy app-directory location, it is copied to the new location once. /// public static string GetConfigPath() { var folder = GetAppDataFolder(); var newPath = Path.Combine(folder, "appsettings.json"); MigrateLegacyConfigIfNeeded(newPath); return newPath; } private static void MigrateLegacyDbIfNeeded(string newPath) { if (File.Exists(newPath)) return; var legacyPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "utopia_canteen.db"); if (!File.Exists(legacyPath)) return; try { File.Copy(legacyPath, newPath); } catch { // If copy fails, app will start with a new DB at new path. } } private static void MigrateLegacyConfigIfNeeded(string newPath) { if (File.Exists(newPath)) return; var legacyPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "appsettings.json"); if (!File.Exists(legacyPath)) return; try { File.Copy(legacyPath, newPath); } catch { // If copy fails, app will start with a new config at new path. } } }