namespace ClaudeDo.Worker.Git;

/// <summary>
/// Resolves the "sibling" worktree root and guards against a worktree landing inside the
/// repository it was created from. A <c>list.WorkingDir</c> ending in a directory separator
/// makes <see cref="Path.GetDirectoryName(string)"/> return the same directory instead of its
/// parent, which used to place <c>.claudedo-worktrees</c> inside the target repo's own tree.
/// </summary>
public static class WorktreeRootResolver
{
    /// <summary>The parent directory of <paramref name="workingDir"/>, trailing-separator safe.</summary>
    public static string ResolveSiblingRoot(string workingDir)
    {
        var full = Path.TrimEndingDirectorySeparator(Path.GetFullPath(workingDir));
        var parent = Path.GetDirectoryName(full);
        if (string.IsNullOrEmpty(parent))
            throw new InvalidOperationException(
                $"Cannot place a sibling worktree next to '{workingDir}': it has no parent directory.");
        return parent;
    }

    /// <summary>Throws if <paramref name="worktreePath"/> is <paramref name="workingDir"/> or lies beneath it.</summary>
    public static void EnsureOutsideWorkingDir(string worktreePath, string workingDir)
    {
        var comparison = OperatingSystem.IsWindows() ? StringComparison.OrdinalIgnoreCase : StringComparison.Ordinal;
        var worktreeFull = Path.GetFullPath(worktreePath);
        var workingDirFull = Path.TrimEndingDirectorySeparator(Path.GetFullPath(workingDir));

        var isInside = worktreeFull.Equals(workingDirFull, comparison)
            || worktreeFull.StartsWith(workingDirFull + Path.DirectorySeparatorChar, comparison);
        if (isInside)
            throw new InvalidOperationException(
                $"Refusing to create worktree '{worktreeFull}' inside the target repository's working " +
                $"tree '{workingDirFull}'. Check list.WorkingDir for a trailing separator or a misconfigured worktree root.");
    }
}
