#!/usr/bin/env nu

# Documentation Link Validator
# Scans all markdown files and validates internal links

const DOCS_ROOT = "/Users/Akasha/project-provisioning/docs"
const PROVISIONING_DOCS_ROOT = "/Users/Akasha/project-provisioning/provisioning/docs"

# Find all markdown files in documentation
def find-all-docs []: nothing -> list<string> {
    let docs_root = "/Users/Akasha/project-provisioning/docs"
    let prov_docs_root = "/Users/Akasha/project-provisioning/provisioning/docs"

    mut all_docs = []

    # Find docs in main docs directory
    let result1 = (do {
        let main_docs = (glob ($docs_root + "/**/*.md"))
        $all_docs = ($all_docs | append $main_docs)
    } | complete)

    # Find docs in provisioning/docs directory
    let result2 = (do {
        let prov_docs = (glob ($prov_docs_root + "/**/*.md"))
        $all_docs = ($all_docs | append $prov_docs)
    } | complete)

    $all_docs | uniq
}

# Extract all markdown links from a file
def extract-links [file: string]: nothing -> table {
    let content = (open $file)
    let lines = ($content | lines)

    mut results = []

    for idx in 0..<($lines | length) {
        let line = ($lines | get $idx)

        # Match markdown links: [text](path)
        let matches = ($line | parse -r '\[([^\]]+)\]\(([^)]+)\)')

        for match in $matches {
            let link_text = ($match | get capture0)
            let link_path = ($match | get capture1)

            # Classify link type
            let link_type = if ($link_path | str starts-with "http") {
                "external"
            } else if ($link_path | str starts-with "#") {
                "anchor"
            } else {
                "internal"
            }

            $results = ($results | append {
                line: ($idx + 1)
                text: $link_text
                path: $link_path
                type: $link_type
            })
        }
    }

    $results
}

# Resolve relative path from source file to target
def resolve-path [source: string, target: string]: nothing -> string {
    let source_dir = ($source | path dirname)

    # Handle absolute paths
    if ($target | str starts-with "/") {
        return $target
    }

    # Handle relative paths
    let resolved = ([$source_dir, $target] | path join)

    # Normalize path (handle ../ and ./)
    $resolved | path expand
}

# Check if a link target exists
def check-link-exists [source: string, link: record]: nothing -> record {
    if $link.type == "external" {
        return ($link | insert exists true | insert resolved $link.path)
    }

    if $link.type == "anchor" {
        # For now, mark anchors as valid (would need to parse headings to validate)
        return ($link | insert exists true | insert resolved $link.path)
    }

    # Internal link - resolve and check existence
    let target_path = (resolve-path $source $link.path)
    let exists = ($target_path | path exists)

    $link | insert exists $exists | insert resolved $target_path
}

# Validate all links in a file
def validate-file-links [file: string]: nothing -> table {
    print $"Checking ($file)..."

    let links = (extract-links $file)

    $links | each {|link|
        let checked = (check-link-exists $file $link)
        $checked | insert source_file $file
    }
}

# Main validation function
def main [
    --fix              # Attempt to fix broken links automatically
    --format: string = "table"  # Output format: table, json, or markdown
] {
    print "📚 Documentation Link Validator"
    print "================================\n"

    print "Finding all documentation files..."
    let docs = (find-all-docs)
    print $"Found ($docs | length) markdown files\n"

    print "Extracting and validating links..."
    mut all_results = []

    for doc in $docs {
        let result = (do {
            let results = (validate-file-links $doc)
            $all_results = ($all_results | append $results)
        } | complete)

        if $result.exit_code != 0 {
            print $"⚠️  Error processing ($doc): ($result.stderr)"
        }
    }

    # Summary statistics
    let total_links = ($all_results | length)
    let internal_links = ($all_results | where type == "internal" | length)
    let external_links = ($all_results | where type == "external" | length)
    let anchor_links = ($all_results | where type == "anchor" | length)
    let broken_links = ($all_results | where exists == false | length)

    print "\n📊 Summary Statistics"
    print "====================="
    print $"Total links found: ($total_links)"
    print $"  Internal links: ($internal_links)"
    print $"  External links: ($external_links)"
    print $"  Anchor links: ($anchor_links)"
    print $"  Broken links: ❌ ($broken_links)"

    # Show broken links if any
    if $broken_links > 0 {
        print "\n❌ Broken Links Report"
        print "======================"

        let broken = ($all_results | where exists == false)

        if $format == "json" {
            $broken | to json
        } else if $format == "markdown" {
            print "| Source File | Line | Link Text | Target Path |"
            print "|-------------|------|-----------|-------------|"
            for link in $broken {
                print $"| ($link.source_file) | ($link.line) | ($link.text) | ($link.path) |"
            }
        } else {
            $broken | select source_file line text path resolved | table -e
        }

        # Save broken links report
        let report_file = "/Users/Akasha/project-provisioning/provisioning/tools/broken-links-report.json"
        $broken | save -f $report_file
        print $"\n💾 Broken links report saved to: ($report_file)"

        if $fix {
            print "\n🔧 Attempting to fix broken links..."
            # TODO: Implement auto-fix logic
            print "⚠️  Auto-fix not yet implemented"
        }
    } else {
        print "\n✅ All links are valid!"
    }

    # Save full validation report
    let full_report_file = "/Users/Akasha/project-provisioning/provisioning/tools/doc-validation-full-report.json"
    $all_results | save -f $full_report_file
    print $"\n💾 Full validation report saved to: ($full_report_file)"

    # Return exit code based on broken links
    if $broken_links > 0 {
        exit 1
    }
}

# Export utility functions for use in other scripts
export def "links find" [file: string] {
    extract-links $file
}

export def "links validate" [file: string] {
    validate-file-links $file
}

export def "links check" [source: string, target: string] {
    let resolved = (resolve-path $source $target)
    {
        source: $source
        target: $target
        resolved: $resolved
        exists: ($resolved | path exists)
    }
}
