// Copyright (c) Tribufu. All Rights Reserved. // SPDX-License-Identifier: MIT using System; using System.IO; using System.Runtime.InteropServices; using Tribufu.Logging; namespace Tribufu.Platform { /// /// Provides standardized access to important directories, such as config, saved data, logs, and platform-specific binaries. /// This is especially useful for abstracting file path logic across environments (development, production, etc). /// public static class Paths { /// /// Gets the root base directory of the application. /// /// /// - In development, this resolves to the root of the repository (five levels above bin/Debug or bin/Release). /// - In production, it resolves to two levels above the binary location. /// - It uses case-insensitive checks and runtime heuristics to improve accuracy. /// /// The absolute path to the base directory. public static string GetApplicationDirectory() { try { string baseDirectory; string defaultBaseDirectory = AppContext.BaseDirectory; bool isDevelopment = defaultBaseDirectory.ToLowerInvariant().Contains("debug"); if (isDevelopment) { // Go 5 levels up to simulate project root baseDirectory = Path.Combine(defaultBaseDirectory, "..", "..", "..", "..", ".."); } else { baseDirectory = Path.Combine(defaultBaseDirectory, "..", ".."); } return Path.GetFullPath(baseDirectory); } catch (Exception ex) { Logger.Warn($"(Paths) Failed to resolve base directory: {ex.Message}"); return AppContext.BaseDirectory; } } /// /// Gets the path to the platform-specific binary directory. /// /// /// The absolute path to bin/<runtime-identifier> if available, /// otherwise falls back to bin/dotnet. /// public static string GetApplicationBinDirectory() { var binDirectory = Path.Combine(GetApplicationDirectory(), "bin"); if (!string.IsNullOrEmpty(RuntimeInformation.RuntimeIdentifier)) { binDirectory = Path.Combine(binDirectory, RuntimeInformation.RuntimeIdentifier); } else { binDirectory = Path.Combine(binDirectory, "dotnet"); } return binDirectory; } /// /// Gets the path to the configuration directory. /// /// The absolute path to the config directory. public static string GetApplicationConfigDirectory() { return Path.Combine(GetApplicationDirectory(), "config"); } /// /// Gets the path to the assets directory. /// /// The absolute path to the assets directory. public static string GetApplicationAssetsDirectory() { return Path.Combine(GetApplicationDirectory(), "assets"); } /// /// Gets the path to the saved data directory. /// /// The absolute path to the saved directory. public static string GetApplicationSavedDirectory() { return Path.Combine(GetApplicationDirectory(), "saved"); } /// /// Gets the path to the cache directory inside saved. /// /// The absolute path to the saved/cache directory. public static string GetApplicationCacheDirectory() { return Path.Combine(GetApplicationSavedDirectory(), "cache"); } /// /// Gets the path to the logs directory inside saved. /// /// The absolute path to the saved/logs directory. public static string GetApplicationLogsDirectory() { return Path.Combine(GetApplicationSavedDirectory(), "logs"); } } }