namespace DodoSSH.Client.ObjectStore;

/// <summary>
/// Translating between the paths a file browser uses and the keys a bucket has.
/// </summary>
/// <remarks>
/// <para>
/// <b>A bucket has no directories.</b> It has keys, which are strings, and a convention that <c>/</c> in a
/// key means what it means in a path. Everything in this class is that convention written down in one place,
/// because the alternative is the same three lines of trimming repeated at every call site with one of them
/// subtly different.
/// </para>
/// <para>
/// The browser's side is an absolute POSIX path — <c>/reports/2026/q3.csv</c> — because that is what the
/// screen, the breadcrumb trail and the transfer queue already speak. The bucket's side is a key with no
/// leading slash: <c>reports/2026/q3.csv</c>. The root is <c>/</c> on one side and the empty string on the
/// other, which is the case every one of these methods is really about.
/// </para>
/// </remarks>
internal static class ObjectKeys
{
    /// <summary>The path a file browser opens on.</summary>
    internal const string Root = "/";

    /// <summary>The object key for a browser path.</summary>
    internal static string ToKey(string path) => path.TrimStart('/');

    /// <summary>The browser path for an object key.</summary>
    internal static string ToPath(string key) => Root + key.TrimStart('/');

    /// <summary>
    /// The prefix that lists one directory's immediate contents.
    /// </summary>
    /// <remarks>
    /// Trailing slash, always, and empty for the root. Without it a listing of <c>/reports</c> would also
    /// return <c>/reports-archive</c>, because a prefix match knows nothing about path segments.
    /// </remarks>
    internal static string ToPrefix(string path)
    {
        var key = ToKey(path);

        return key.Length == 0 || key.EndsWith('/') ? key : key + "/";
    }

    /// <summary>The last segment of a key, which is what a row shows.</summary>
    /// <remarks>
    /// Trailing slashes are removed first, so the common prefix <c>reports/2026/</c> yields <c>2026</c>
    /// rather than an empty string.
    /// </remarks>
    internal static string NameOf(string key)
    {
        var trimmed = key.TrimEnd('/');
        var slash = trimmed.LastIndexOf('/');

        return slash < 0 ? trimmed : trimmed[(slash + 1)..];
    }
}
