using Sdt.Config;
using Xunit;

namespace DevTool.Tests;

public sealed class ConfigBootstrapperTests
{
    [Fact]
    public void Scan_DetectsDotnetAndNode()
    {
        var root = CreateTempDir();
        File.WriteAllText(Path.Combine(root, "sample.sln"), "");
        File.WriteAllText(Path.Combine(root, "package.json"), "{}");

        var scan = ConfigBootstrapper.Scan(root);

        Assert.Contains("dotnet", scan.ToolFamilies, StringComparer.OrdinalIgnoreCase);
        Assert.Contains("node", scan.ToolFamilies, StringComparer.OrdinalIgnoreCase);
        Assert.Contains("npm", scan.ToolFamilies, StringComparer.OrdinalIgnoreCase);
    }

    [Fact]
    public void Scan_DetectsPythonFromScriptsDirectory()
    {
        var root = CreateTempDir();
        var scripts = Path.Combine(root, "scripts");
        Directory.CreateDirectory(scripts);
        File.WriteAllText(Path.Combine(scripts, "publish-app.py"), "print('ok')");

        var scan = ConfigBootstrapper.Scan(root);
        Assert.Contains("python", scan.ToolFamilies, StringComparer.OrdinalIgnoreCase);
    }

    [Fact]
    public void BuildDefaultConfig_ProducesWorkflowsAndDebugSection()
    {
        var scan = new BootstrapScanResult(
            ProjectRoot: Path.GetTempPath(),
            ProjectName: "demo",
            ToolFamilies: ["dotnet", "git"],
            NodeWorkingDir: null,
            PythonRequirementsFile: null,
            HasDockerCompose: false,
            RootHints: ["*.sln"]);

        var cfg = ConfigBootstrapper.BuildDefaultConfig(scan);

        Assert.NotNull(cfg.Debug);
        Assert.Contains(cfg.Workflows, w => w.Id == "build");
        Assert.Contains(cfg.Workflows, w => w.Id == "repo-health");
        Assert.False(cfg.Debug!.Diagnostics.IncludeAllEnv);
        Assert.Contains("SDT_LOG_LEVEL", cfg.Debug.Diagnostics.CaptureEnvKeys);
    }

    [Fact]
    public void BuildDefaultConfig_IncludesScriptDrivenWorkflow_WhenHelpersExist()
    {
        var root = CreateTempDir();
        var scripts = Path.Combine(root, "scripts");
        Directory.CreateDirectory(scripts);
        File.WriteAllText(Path.Combine(scripts, "publish-app.py"), "print('ok')");
        File.WriteAllText(Path.Combine(scripts, "publish-sidecar.py"), "print('ok')");

        var scan = ConfigBootstrapper.Scan(root);
        var cfg = ConfigBootstrapper.BuildDefaultConfig(scan);

        Assert.Contains(cfg.Workflows, w => w.Id == "web");
        Assert.Contains(cfg.Workflows, w => w.Id == "sidecar");
    }

    [Fact]
    public void WriteDefaultConfig_WritesDevtoolJson()
    {
        var root = CreateTempDir();
        var scan = new BootstrapScanResult(
            ProjectRoot: root,
            ProjectName: "demo",
            ToolFamilies: ["dotnet"],
            NodeWorkingDir: null,
            PythonRequirementsFile: null,
            HasDockerCompose: false,
            RootHints: ["*.sln"]);
        var cfg = ConfigBootstrapper.BuildDefaultConfig(scan);

        var path = ConfigBootstrapper.WriteDefaultConfig(root, cfg);

        Assert.True(File.Exists(path));
    }

    [Fact]
    public void Scan_IgnoresExcludedDirectories_ForToolDetection()
    {
        var root = CreateTempDir();
        var nodeModules = Path.Combine(root, "node_modules", "nested");
        Directory.CreateDirectory(nodeModules);
        File.WriteAllText(Path.Combine(nodeModules, "package.json"), "{}");

        var scan = ConfigBootstrapper.Scan(root);
        Assert.DoesNotContain("node", scan.ToolFamilies, StringComparer.OrdinalIgnoreCase);
    }

    private static string CreateTempDir()
    {
        var path = Path.Combine(Path.GetTempPath(), "sdt-bootstrap-" + Guid.NewGuid().ToString("N"));
        Directory.CreateDirectory(path);
        return path;
    }
}
