Private/Resolve-DataPath.ps1

# Copyright (c) 2026 Jeffrey Snover. All rights reserved.
# Licensed under the MIT License. See LICENSE file in the project root.

# ── Data path resolution ──
# Reads .aitriad.json to determine where data lives.
# Priority: $env:AI_TRIAD_DATA_ROOT > .aitriad.json > platform default

$script:DataConfig = $null

function Get-PlatformDataDir {
    <#
    .SYNOPSIS
        Returns the platform-appropriate default data directory for AITriad.
    #>

    if ($IsWindows) {
        return Join-Path $env:LOCALAPPDATA 'AITriad' 'data'
    }
    elseif ($IsMacOS) {
        return Join-Path $HOME 'Library' 'Application Support' 'AITriad' 'data'
    }
    else {
        # Linux — XDG Base Directory spec
        $XdgData = $env:XDG_DATA_HOME
        if ([string]::IsNullOrWhiteSpace($XdgData)) {
            $XdgData = Join-Path $HOME '.local' 'share'
        }
        return Join-Path $XdgData 'aitriad' 'data'
    }
}

function Initialize-DataConfig {
    if ($null -ne $script:DataConfig) { return }

    # Try to load .aitriad.json from repo root (dev) or module root (PSGallery)
    $ConfigPaths = @(
        (Join-Path $script:RepoRoot '.aitriad.json')
        (Join-Path $script:ModuleRoot '.aitriad.json')
    )

    foreach ($ConfigPath in $ConfigPaths) {
        if (Test-Path $ConfigPath) {
            try {
                $script:DataConfig = Get-Content -Raw -Path $ConfigPath | ConvertFrom-Json
                Write-Verbose "Data config: loaded from $ConfigPath"
                return
            }
            catch {
                Write-Warning "Failed to load .aitriad.json: $($_.Exception.Message)"
            }
        }
    }

    # Fallback defaults — use platform-specific data dir for PSGallery installs
    $DefaultRoot = if ($script:IsDevInstall) { '.' } else { Get-PlatformDataDir }

    $script:DataConfig = [PSCustomObject]@{
        data_root     = $DefaultRoot
        taxonomy_dir  = 'taxonomy/Origin'
        sources_dir   = 'sources'
        summaries_dir = 'summaries'
        conflicts_dir = 'conflicts'
        debates_dir   = 'debates'
        queue_file    = '.summarise-queue.json'
        version_file  = 'TAXONOMY_VERSION'
    }
    Write-Verbose "Data config: using defaults (data_root=$DefaultRoot)"
}

function Get-DataRoot {
    <#
    .SYNOPSIS
        Returns the resolved absolute path to the data root directory.
    #>

    Initialize-DataConfig

    # Env var takes highest priority
    if (-not [string]::IsNullOrWhiteSpace($env:AI_TRIAD_DATA_ROOT)) {
        $Resolved = Resolve-Path $env:AI_TRIAD_DATA_ROOT -ErrorAction SilentlyContinue
        if ($Resolved) { return $Resolved.Path }
        return $env:AI_TRIAD_DATA_ROOT
    }

    $Root = $script:DataConfig.data_root
    if ([System.IO.Path]::IsPathRooted($Root)) {
        return $Root
    }
    return Join-Path $script:RepoRoot $Root
}

function Get-TaxonomyDir {
    <#
    .SYNOPSIS
        Returns the absolute path to the taxonomy directory (e.g. taxonomy/Origin).
    #>

    Initialize-DataConfig
    $Dir = $script:DataConfig.taxonomy_dir
    if ([System.IO.Path]::IsPathRooted($Dir)) { return $Dir }
    return Join-Path (Get-DataRoot) $Dir
}

function Get-SourcesDir {
    Initialize-DataConfig
    $Dir = $script:DataConfig.sources_dir
    if ([System.IO.Path]::IsPathRooted($Dir)) { return $Dir }
    return Join-Path (Get-DataRoot) $Dir
}

function Get-SummariesDir {
    Initialize-DataConfig
    $Dir = $script:DataConfig.summaries_dir
    if ([System.IO.Path]::IsPathRooted($Dir)) { return $Dir }
    return Join-Path (Get-DataRoot) $Dir
}

function Get-ConflictsDir {
    Initialize-DataConfig
    $Dir = $script:DataConfig.conflicts_dir
    if ([System.IO.Path]::IsPathRooted($Dir)) { return $Dir }
    return Join-Path (Get-DataRoot) $Dir
}

function Get-DebatesDir {
    Initialize-DataConfig
    $Dir = $script:DataConfig.debates_dir
    if ([System.IO.Path]::IsPathRooted($Dir)) { return $Dir }
    return Join-Path (Get-DataRoot) $Dir
}

function Get-QueueFile {
    Initialize-DataConfig
    $File = $script:DataConfig.queue_file
    if ([System.IO.Path]::IsPathRooted($File)) { return $File }
    return Join-Path (Get-DataRoot) $File
}

function Get-VersionFile {
    Initialize-DataConfig
    $File = $script:DataConfig.version_file
    if ([System.IO.Path]::IsPathRooted($File)) { return $File }
    return Join-Path (Get-DataRoot) $File
}