# Gitea Integration Tests
#
# Comprehensive test suite for Gitea functionality
#
# Version: 1.0.0

use ../lib_provisioning/gitea/mod.nu *

# Test configuration
const TEST_ORG = "test-provisioning"
const TEST_REPO = "test-repo"
const TEST_WORKSPACE = "test-workspace"

# Setup test environment
def setup-test-env [] {
    print "Setting up test environment..."

    # Check if Gitea is running
    let status = get-gitea-status

    if not $status.running {
        print "⚠️  Gitea is not running. Starting Gitea..."
        start-gitea
        sleep 5sec
    }

    # Validate token
    let valid = validate-token

    if not $valid {
        error make {
            msg: "Invalid Gitea token"
            help: "Configure Gitea authentication before running tests"
        }
    }

    print "✓ Test environment ready"
}

# Cleanup test environment
def cleanup-test-env [] {
    print "Cleaning up test environment..."

    # Delete test repositories
    let result = (do { delete-repository $TEST_ORG $TEST_REPO --force } | complete)

    print "✓ Cleanup complete"
}

# Test: API Client
export def test-api-client [] {
    print "Testing API Client..."

    # Test get current user
    let user = get-current-user
    assert ($user.login != null) "Current user should have login"

    # Test validate token
    let valid = validate-token
    assert $valid "Token should be valid"

    print "✓ API Client tests passed"
}

# Test: Repository Operations
export def test-repository-operations [] {
    print "Testing Repository Operations..."

    # Create test organization if needed
    let result = (do { get-organization $TEST_ORG } | complete)
    if $result.exit_code != 0 {
        create-organization $TEST_ORG "Test organization"
    }

    # Create repository
    let repo = create-repository $TEST_ORG $TEST_REPO "Test repository" true

    assert ($repo.name == $TEST_REPO) "Repository name should match"
    assert ($repo.owner.username == $TEST_ORG) "Repository owner should match"

    # Get repository
    let fetched_repo = get-repository $TEST_ORG $TEST_REPO
    assert ($fetched_repo.name == $TEST_REPO) "Fetched repository name should match"

    # List repositories
    let repos = list-repositories $TEST_ORG
    assert (($repos | where name == $TEST_REPO | length) > 0) "Repository should be in list"

    # Delete repository
    delete-repository $TEST_ORG $TEST_REPO --force
    print "✓ Repository Operations tests passed"
}

# Test: Release Operations
export def test-release-operations [] {
    print "Testing Release Operations..."

    # Create test repository
    let result = (do { get-organization $TEST_ORG } | complete)
    if $result.exit_code != 0 {
        create-organization $TEST_ORG "Test organization"
    }

    let repo = create-repository $TEST_ORG $TEST_REPO "Test repository" true

    # Create release
    let release = create-release $TEST_ORG $TEST_REPO "v1.0.0" "Test Release" "Release notes"

    assert ($release.tag_name == "v1.0.0") "Release tag should match"
    assert ($release.name == "Test Release") "Release name should match"

    # Get release by tag
    let fetched_release = get-release-by-tag $TEST_ORG $TEST_REPO "v1.0.0"
    assert ($fetched_release.tag_name == "v1.0.0") "Fetched release tag should match"

    # List releases
    let releases = list-releases $TEST_ORG $TEST_REPO
    assert (($releases | where tag_name == "v1.0.0" | length) > 0) "Release should be in list"

    # Cleanup
    delete-repository $TEST_ORG $TEST_REPO --force

    print "✓ Release Operations tests passed"
}

# Test: Issue Operations (Locking)
export def test-issue-operations [] {
    print "Testing Issue Operations..."

    # Create test repository
    let result = (do { get-organization $TEST_ORG } | complete)
    if $result.exit_code != 0 {
        create-organization $TEST_ORG "Test organization"
    }

    let repo = create-repository $TEST_ORG $TEST_REPO "Test repository" true

    # Create issue
    let issue = create-issue $TEST_ORG $TEST_REPO "Test Issue" "Issue body" ["test"]

    assert ($issue.title == "Test Issue") "Issue title should match"

    # List issues
    let issues = list-issues $TEST_ORG $TEST_REPO "open"
    assert (($issues | where title == "Test Issue" | length) > 0) "Issue should be in list"

    # Close issue
    close-issue $TEST_ORG $TEST_REPO $issue.number

    # Verify closed
    let closed_issues = list-issues $TEST_ORG $TEST_REPO "closed"
    assert (($closed_issues | where number == $issue.number | length) > 0) "Issue should be closed"

    # Cleanup
    delete-repository $TEST_ORG $TEST_REPO --force

    print "✓ Issue Operations tests passed"
}

# Test: Workspace Locking
export def test-workspace-locking [] {
    print "Testing Workspace Locking..."

    # Acquire lock
    let lock = acquire-workspace-lock $TEST_WORKSPACE "write" "Test operation"

    assert ($lock.workspace == $TEST_WORKSPACE) "Lock workspace should match"
    assert ($lock.lock_type == "write") "Lock type should match"

    # Check if locked
    let is_locked = is-workspace-locked $TEST_WORKSPACE "write"
    assert $is_locked "Workspace should be locked"

    # List locks
    let locks = list-workspace-locks $TEST_WORKSPACE
    assert (($locks | where number == $lock.lock_id | length) > 0) "Lock should be in list"

    # Get lock info
    let lock_info = get-lock-info $TEST_WORKSPACE $lock.lock_id
    assert ($lock_info.lock_id == $lock.lock_id) "Lock ID should match"

    # Release lock
    release-workspace-lock $TEST_WORKSPACE $lock.lock_id

    # Verify released
    let is_still_locked = is-workspace-locked $TEST_WORKSPACE "write"
    assert (not $is_still_locked) "Workspace should be unlocked"

    print "✓ Workspace Locking tests passed"
}

# Test: Service Management
export def test-service-management [] {
    print "Testing Service Management..."

    # Get status
    let status = get-gitea-status
    assert ($status.mode != null) "Status should have mode"

    # Check health
    let healthy = check-gitea-health
    assert $healthy "Gitea should be healthy"

    print "✓ Service Management tests passed"
}

# Test: Workspace Git Operations (mock)
export def test-workspace-git-mock [] {
    print "Testing Workspace Git Operations (mock)..."

    # Create temporary workspace
    let temp_ws = $"/tmp/test-workspace-(random chars -l 8)"
    mkdir $temp_ws

    # Initialize git
    cd $temp_ws
    ^git init
    ^git config user.name "Test User"
    ^git config user.email "test@example.com"

    # Create test file
    "test content" | save test.txt
    ^git add test.txt
    ^git commit -m "Initial commit"

    # Test git status
    let status = get-workspace-git-status $temp_ws
    assert ($status.is_git_repo == true) "Should be git repo"
    assert ($status.branch == "master" or $status.branch == "main") "Should have branch"

    # Cleanup
    rm -rf $temp_ws

    print "✓ Workspace Git Operations tests passed"
}

# Test: Extension Publishing (mock)
export def test-extension-publishing-mock [] {
    print "Testing Extension Publishing (mock)..."

    # Create temporary extension
    let temp_ext = $"/tmp/test-extension-(random chars -l 8)"
    mkdir $temp_ext
    mkdir $"($temp_ext)/nickel"

    # Create minimal extension structure
    {
        package = {
            name = "test-extension"
            version = "1.0.0"
        }
    } | save -f $"($temp_ext)/nickel/nickel.mod"

    "schema TestExtension:\n    name: str" | save -f $"($temp_ext)/nickel/test.ncl"

    # Validate extension
    let validation = validate-extension $temp_ext
    assert ($validation.valid == true) "Extension should be valid"
    assert ($validation.extension_name == ($temp_ext | path basename)) "Extension name should match"

    # Cleanup
    rm -rf $temp_ext

    print "✓ Extension Publishing tests passed"
}

# Run all tests
export def run-all-tests [
    --skip-integration: bool = false
] {
    print "Running Gitea Integration Tests"
    print "================================"
    print ""

    if not $skip_integration {
        setup-test-env
    }

    # Run tests
    test-api-client
    test-service-management
    test-workspace-git-mock
    test-extension-publishing-mock

    if not $skip_integration {
        test-repository-operations
        test-release-operations
        test-issue-operations
        test-workspace-locking
    }

    print ""
    print "================================"
    print "✓ All tests passed!"
}

# Helper assertion function
def assert [
    condition: bool
    message: string
] {
    if not $condition {
        error make {
            msg: $"Assertion failed: ($message)"
        }
    }
}
