workspace.psm1

# Workspace module for Delta-Code
# Manages workspace registry, active context, and context switching

# Resolve module dependencies from the sibling directory when available (repository
# and flat-install layouts) and fall back to module-name resolution (PSGallery).
foreach ($dependencyName in @('delta-code', 'satellite')) {
    $dependencyManifest = Join-Path $PSScriptRoot "$dependencyName.psd1"
    if (Test-Path -LiteralPath $dependencyManifest) {
        Import-Module $dependencyManifest -ErrorAction Stop -DisableNameChecking
    }
    else {
        Import-Module $dependencyName -ErrorAction Stop -DisableNameChecking
    }
}
Remove-Variable dependencyName, dependencyManifest -ErrorAction SilentlyContinue

$script:WorkspaceRegistryPath = Join-Path (Split-Path $PSScriptRoot) "data\workspaces.json"
$script:WorkspaceRegistry = @{}
$script:ActiveWorkspace = $null

function Save-WorkspaceRegistry {
    $data = @{
        Workspaces = $script:WorkspaceRegistry.Values
        ActiveWorkspace = if ($script:ActiveWorkspace) { $script:ActiveWorkspace.Name } else { $null }
    }
    $data | ConvertTo-Json -Depth 5 | Set-Content -Path $script:WorkspaceRegistryPath -Encoding UTF8
}

function Load-WorkspaceRegistry {
    if (Test-Path $script:WorkspaceRegistryPath) {
        $data = Get-Content $script:WorkspaceRegistryPath -Raw | ConvertFrom-Json
        if ($data.Workspaces) {
            $script:WorkspaceRegistry = @{}
            foreach ($ws in $data.Workspaces) {
                $script:WorkspaceRegistry[$ws.Name] = $ws
            }
        }
        if ($data.ActiveWorkspace) {
            $script:ActiveWorkspace = $script:WorkspaceRegistry[$data.ActiveWorkspace]
        }
    }
}

# Load registry on module import
Load-WorkspaceRegistry

function Get-DeltaCodeWorkspace {
    [CmdletBinding()]
    param(
        [Parameter(Mandatory = $true, Position = 0)]
        [string]$Name
    )
    Load-WorkspaceRegistry
    if ($script:WorkspaceRegistry.ContainsKey($Name)) {
        return $script:WorkspaceRegistry[$Name]
    }
    Write-Error "Workspace '$Name' not found in registry"
    return $null
}

function Get-DeltaCodeWorkspaces {
    [CmdletBinding()]
    param(
        [string[]]$Filter
    )
    Load-WorkspaceRegistry
    $ws = $script:WorkspaceRegistry.Values
    if ($Filter) {
        $ws = $ws | Where-Object { $Filter -contains $_.Category }
    }
    return $ws
}

function Register-DeltaCodeWorkspace {
    [CmdletBinding()]
    param(
        [Parameter(Mandatory = $true, Position = 0)]
        [string]$Name,
        [Parameter(Mandatory = $true, Position = 1)]
        [string]$Root,
        [Parameter(Mandatory = $false)]
        [string]$Category = 'General',
        [Parameter(Mandatory = $false)]
        [string]$Satellite = $null,
        [Parameter(Mandatory = $false)]
        [string]$Description = '',
        [Parameter(Mandatory = $false)]
        [hashtable]$Metadata = @{}
    )
    Load-WorkspaceRegistry
    $normalizedRoot = (Resolve-Path -LiteralPath $Root).ProviderPath
    if (-not (Test-Path $normalizedRoot)) {
        Write-Error "Workspace root path does not exist: $normalizedRoot"
        return $false
    }

    $workspace = [PSCustomObject]@{
        Name        = $Name
        Root        = $normalizedRoot
        Category    = $Category
        Satellite   = $Satellite
        Description = $Description
        Metadata    = $Metadata
        Registered  = (Get-Date -Format 'yyyy-MM-dd HH:mm:ss')
        Active      = $false
    }

    $script:WorkspaceRegistry[$Name] = $workspace
    Save-WorkspaceRegistry
    Write-Verbose "Registered workspace '$Name' at $normalizedRoot"
    return $true
}

function Set-DeltaCodeWorkspace {
    [CmdletBinding()]
    param(
        [Parameter(Mandatory = $true, Position = 0)]
        [string]$Name
    )
    Load-WorkspaceRegistry
    $ws = Get-DeltaCodeWorkspace -Name $Name
    if (-not $ws) { return $false }

    if ($script:ActiveWorkspace) {
        $script:ActiveWorkspace.Active = $false
    }
    $ws.Active = $true
    $script:ActiveWorkspace = $ws
    Save-WorkspaceRegistry
    Write-Verbose "Active workspace set to '$Name' ($($ws.Root))"
    return $true
}

function Test-DeltaCodeWorkspace {
    [CmdletBinding()]
    param(
        [Parameter(Mandatory = $true, Position = 0)]
        [string]$Name
    )
    Load-WorkspaceRegistry
    $ws = Get-DeltaCodeWorkspace -Name $Name
    if (-not $ws) { return $false }

    $valid = $true
    $issues = @()

    if (-not (Test-Path $ws.Root)) {
        $issues += "Workspace root does not exist: $($ws.Root)"
        $valid = $false
    }
    if ($ws.Satellite) {
        $sat = Get-DeltaCodeSatellite -Name $ws.Satellite
        if (-not $sat) {
            $issues += "Referenced satellite not found: $($ws.Satellite)"
            $valid = $false
        }
    }

    if (-not $valid) {
        Write-Warning "Workspace '$Name' validation failed: $($issues -join '; ')"
    }
    else {
        Write-Verbose "Workspace '$Name' validated successfully"
    }
    return $valid
}

function Initialize-DeltaCodeWorkspaces {
    [CmdletBinding()]
    param(
        [string[]]$SearchPaths
    )
    Load-WorkspaceRegistry
    if (-not $SearchPaths) {
        $SearchPaths = @(
            "$PSScriptRoot\workspaces",
            "$PSScriptRoot\..\workspaces",
            (Join-Path $env:USERPROFILE ".delta-code\workspaces")
        )
    }

    foreach ($basePath in $SearchPaths) {
        if (Test-Path $basePath) {
            $dirs = Get-ChildItem -Path $basePath -Directory
            foreach ($dir in $dirs) {
                $wsName = $dir.Name
                $wsPath = $dir.FullName
                $manifest = Join-Path $wsPath "$wsName.json"
                if (Test-Path $manifest) {
                    $config = Get-Content $manifest -Raw | ConvertFrom-Json
                    Register-DeltaCodeWorkspace -Name $wsName -Path $wsPath -Category $config.Category -Satellite $config.Satellite -Description $config.Description -Metadata $config.Metadata
                }
            }
        }
    }

    # Auto-validate all registered
    $names = @($script:WorkspaceRegistry.Keys)
    foreach ($name in $names) {
        Test-DeltaCodeWorkspace -Name $name
    }
}

function Unregister-DeltaCodeWorkspace {
    [CmdletBinding()]
    param(
        [Parameter(Mandatory = $true, Position = 0)]
        [string]$Name
    )
    Load-WorkspaceRegistry
    if ($script:WorkspaceRegistry.ContainsKey($Name)) {
        if ($script:ActiveWorkspace -and $script:ActiveWorkspace.Name -eq $Name) {
            $script:ActiveWorkspace = $null
        }
        $script:WorkspaceRegistry.Remove($Name)
        Save-WorkspaceRegistry
        Write-Verbose "Unregistered workspace '$Name'"
        return $true
    }
    return $false
}

function Get-DeltaCodeActiveWorkspace {
    [CmdletBinding()]
    param()
    Load-WorkspaceRegistry
    return $script:ActiveWorkspace
}

Export-ModuleMember -Function @(
    'Get-DeltaCodeWorkspace'
    'Get-DeltaCodeWorkspaces'
    'Register-DeltaCodeWorkspace'
    'Set-DeltaCodeWorkspace'
    'Test-DeltaCodeWorkspace'
    'Initialize-DeltaCodeWorkspaces'
    'Unregister-DeltaCodeWorkspace'
    'Get-DeltaCodeActiveWorkspace'
)