#!/usr/bin/env bats
# Performance benchmark tests for Mole optimizations
# Tests the performance improvements introduced in V1.14.0+

setup_file() {
    PROJECT_ROOT="$(cd "${BATS_TEST_DIRNAME}/.." && pwd)"
    export PROJECT_ROOT

    # Create test data directory
    TEST_DATA_DIR="$(mktemp -d "${BATS_TEST_DIRNAME}/tmp-perf.XXXXXX")"
    export TEST_DATA_DIR
}

teardown_file() {
    rm -rf "$TEST_DATA_DIR"
}

setup() {
    source "$PROJECT_ROOT/lib/core/base.sh"
}

# ============================================================================
# bytes_to_human Performance Tests
# ============================================================================

@test "bytes_to_human handles large values efficiently" {
    local start end elapsed

    # Warm up
    bytes_to_human 1073741824 > /dev/null

    # Benchmark: 1000 iterations should complete in < 2 seconds (relaxed threshold)
    start=$(date +%s%N)
    for i in {1..1000}; do
        bytes_to_human 1073741824 > /dev/null
    done
    end=$(date +%s%N)

    elapsed=$(( (end - start) / 1000000 )) # Convert to milliseconds

    # Should complete in less than 2000ms (2 seconds)
    [ "$elapsed" -lt 2000 ]
}

@test "bytes_to_human produces correct output for GB range" {
    result=$(bytes_to_human 1073741824)
    [ "$result" = "1.00GB" ]

    result=$(bytes_to_human 5368709120)
    [ "$result" = "5.00GB" ]
}

@test "bytes_to_human produces correct output for MB range" {
    result=$(bytes_to_human 1048576)
    [ "$result" = "1.0MB" ]

    result=$(bytes_to_human 104857600)
    [ "$result" = "100.0MB" ]
}

@test "bytes_to_human produces correct output for KB range" {
    result=$(bytes_to_human 1024)
    [ "$result" = "1KB" ]

    result=$(bytes_to_human 10240)
    [ "$result" = "10KB" ]
}

@test "bytes_to_human handles edge cases" {
    # Zero bytes
    result=$(bytes_to_human 0)
    [ "$result" = "0B" ]

    # Invalid input returns 0B (with error code 1)
    run bytes_to_human "invalid"
    [ "$status" -eq 1 ]
    [ "$output" = "0B" ]

    # Negative should also fail validation
    run bytes_to_human "-100"
    [ "$status" -eq 1 ]
    [ "$output" = "0B" ]
}

# ============================================================================
# BSD Stat Wrapper Performance Tests
# ============================================================================

@test "get_file_size is faster than multiple stat calls" {
    # Create test file
    local test_file="$TEST_DATA_DIR/size_test.txt"
    dd if=/dev/zero of="$test_file" bs=1024 count=100 2> /dev/null

    # Benchmark: 100 calls should complete quickly
    local start end elapsed
    start=$(date +%s%N)
    for i in {1..100}; do
        get_file_size "$test_file" > /dev/null
    done
    end=$(date +%s%N)

    elapsed=$(( (end - start) / 1000000 ))

    # Should complete in less than 1000ms (relaxed threshold)
    [ "$elapsed" -lt 1000 ]
}

@test "get_file_mtime returns valid timestamp" {
    local test_file="$TEST_DATA_DIR/mtime_test.txt"
    touch "$test_file"

    result=$(get_file_mtime "$test_file")

    # Should be a valid epoch timestamp (10 digits)
    [[ "$result" =~ ^[0-9]{10,}$ ]]
}

@test "get_file_owner returns current user for owned files" {
    local test_file="$TEST_DATA_DIR/owner_test.txt"
    touch "$test_file"

    result=$(get_file_owner "$test_file")
    current_user=$(whoami)

    [ "$result" = "$current_user" ]
}

# ============================================================================
# User Context Detection Performance Tests
# ============================================================================

@test "get_invoking_user executes quickly" {
    local start end elapsed

    start=$(date +%s%N)
    for i in {1..100}; do
        get_invoking_user > /dev/null
    done
    end=$(date +%s%N)

    elapsed=$(( (end - start) / 1000000 ))

    # Should complete in less than 200ms
    [ "$elapsed" -lt 200 ]
}

@test "get_darwin_major caches correctly" {
    # Multiple calls should return same result
    local first second
    first=$(get_darwin_major)
    second=$(get_darwin_major)

    [ "$first" = "$second" ]
    [[ "$first" =~ ^[0-9]+$ ]]
}

# ============================================================================
# Temporary File Management Performance Tests
# ============================================================================

@test "create_temp_file and cleanup_temp_files work efficiently" {
    local start end elapsed

    # Ensure MOLE_TEMP_DIRS is initialized (base.sh should do this)
    declare -a MOLE_TEMP_DIRS=()

    # Create 50 temp files (reduced from 100 for faster testing)
    start=$(date +%s%N)
    for i in {1..50}; do
        create_temp_file > /dev/null
    done
    end=$(date +%s%N)

    elapsed=$(( (end - start) / 1000000 ))

    # Should complete in less than 1000ms
    [ "$elapsed" -lt 1000 ]

    # Verify temp files were tracked
    [ "${#MOLE_TEMP_FILES[@]}" -eq 50 ]

    # Cleanup should also be reasonably fast
    start=$(date +%s%N)
    cleanup_temp_files
    end=$(date +%s%N)

    elapsed=$(( (end - start) / 1000000 ))
    # Relaxed threshold: should complete within 2 seconds
    [ "$elapsed" -lt 2000 ]

    # Verify cleanup
    [ "${#MOLE_TEMP_FILES[@]}" -eq 0 ]
}

@test "mktemp_file creates files with correct prefix" {
    local temp_file
    temp_file=$(mktemp_file "test_prefix")

    # Should contain prefix
    [[ "$temp_file" =~ test_prefix ]]

    # Should exist
    [ -f "$temp_file" ]

    # Cleanup
    rm -f "$temp_file"
}

# ============================================================================
# Brand Name Lookup Performance Tests
# ============================================================================

@test "get_brand_name handles common apps efficiently" {
    local start end elapsed

    # Warm up (first call includes defaults read which is slow)
    get_brand_name "wechat" > /dev/null

    # Benchmark: 50 lookups (reduced from 100)
    start=$(date +%s%N)
    for i in {1..50}; do
        get_brand_name "wechat" > /dev/null
        get_brand_name "QQ" > /dev/null
        get_brand_name "dingtalk" > /dev/null
    done
    end=$(date +%s%N)

    elapsed=$(( (end - start) / 1000000 ))

    # Relaxed threshold: defaults read is called multiple times
    # Should complete within 5 seconds on most systems
    [ "$elapsed" -lt 5000 ]
}

@test "get_brand_name returns correct localized names" {
    # Test should work regardless of system language
    local result
    result=$(get_brand_name "wechat")

    # Should return either "WeChat" or "微信"
    [[ "$result" == "WeChat" || "$result" == "微信" ]]
}

# ============================================================================
# Parallel Job Calculation Tests
# ============================================================================

@test "get_optimal_parallel_jobs returns sensible values" {
    local result

    # Default mode
    result=$(get_optimal_parallel_jobs)
    [[ "$result" =~ ^[0-9]+$ ]]
    [ "$result" -gt 0 ]
    [ "$result" -le 128 ]

    # Scan mode (should be higher)
    local scan_jobs
    scan_jobs=$(get_optimal_parallel_jobs "scan")
    [ "$scan_jobs" -gt "$result" ]

    # Compute mode (should be lower)
    local compute_jobs
    compute_jobs=$(get_optimal_parallel_jobs "compute")
    [ "$compute_jobs" -le "$scan_jobs" ]
}

# ============================================================================
# Section Tracking Performance Tests
# ============================================================================

@test "section tracking has minimal overhead" {
    local start end elapsed

    # Warm up
    note_activity

    start=$(date +%s%N)
    for i in {1..1000}; do
        note_activity
    done
    end=$(date +%s%N)

    elapsed=$(( (end - start) / 1000000 ))

    # Should complete in less than 1000ms (relaxed threshold)
    [ "$elapsed" -lt 1000 ]
}
