using Kompas.Mcp.Core.Documents;

namespace Kompas.Mcp.Tests;

/// <summary>
/// Подготовка пути записи. КОМПАС в несуществующую папку молча не пишет, а инструмент рапортовал
/// «Сохранено» либо винил занятое имя файла — агент уходил чинить не ту причину.
/// </summary>
[Trait("Category", "Unit")]
public sealed class OutputPathTests : IDisposable
{
    private readonly string _root = Path.Combine(Path.GetTempPath(), "kompas-mcp-tests", Guid.NewGuid().ToString("N")[..8]);

    [Fact]
    public void Missing_directory_is_created()
    {
        var path = Path.Combine(_root, "вложенная папка", "деталь.m3d");

        var full = OutputPath.Prepare(path);

        Assert.Equal(path, full);
        Assert.True(Directory.Exists(Path.GetDirectoryName(full)), "каталог назначения не создан");
        Assert.False(File.Exists(full), "сам файл создавать не нужно — его пишет КОМПАС");
    }

    [Fact]
    public void Relative_path_becomes_absolute()
    {
        var full = OutputPath.Prepare("деталь.m3d");

        Assert.True(Path.IsPathRooted(full), "относительный путь КОМПАС трактует от своего каталога");
    }

    [Theory]
    [InlineData(null)]
    [InlineData("")]
    [InlineData("   ")]
    public void Empty_path_is_rejected(string? path)
        => Assert.Throws<ArgumentException>(() => OutputPath.Prepare(path));

    [Fact]
    public void Directory_without_a_file_name_is_rejected()
    {
        var ex = Assert.Throws<ArgumentException>(() => OutputPath.Prepare(_root + Path.DirectorySeparatorChar));
        Assert.Contains("каталог", ex.Message, StringComparison.OrdinalIgnoreCase);
    }

    [Fact]
    public void Existing_directory_is_left_alone()
    {
        Directory.CreateDirectory(_root);
        var marker = Path.Combine(_root, "уже был.txt");
        File.WriteAllText(marker, "x");

        OutputPath.Prepare(Path.Combine(_root, "деталь.m3d"));

        Assert.True(File.Exists(marker), "подготовка пути не должна трогать содержимое каталога");
    }

    public void Dispose()
    {
        try { if (Directory.Exists(_root)) Directory.Delete(_root, recursive: true); }
        catch (IOException) { /* временный каталог подчистит система */ }
    }
}
