// 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");
}
}
}