# Test helpers for GoodMem installer tests

# Create a fake docker binary with specified compose version
make_fake_docker_with_compose_version() {
    local version="$1"
    local tmp="$BATS_TEST_TMPDIR/fakebin"
    mkdir -p "$tmp"
    cat > "$tmp/docker" <<EOF
#!/usr/bin/env bash
if [[ "\$1" == "compose" && "\$2" == "version" ]]; then
    echo "Docker Compose version v${version}"
    exit 0
fi
# For other docker commands, just succeed
exit 0
EOF
    chmod +x "$tmp/docker"
    export PATH="$tmp:$PATH"
    COMPOSE_BIN=(docker compose)
}

# Create a fake curl that fails N times then succeeds
make_fake_curl_with_retry_count() {
    local fail_count="$1"
    local tmp="$BATS_TEST_TMPDIR/fakebin"
    mkdir -p "$tmp"
    cat > "$tmp/curl" <<EOF
#!/usr/bin/env bash
COUNT_FILE="\${BATS_TEST_TMPDIR}/curl_count"
if [[ ! -f "\${COUNT_FILE}" ]]; then echo 0 > "\${COUNT_FILE}"; fi
n=\$(cat "\${COUNT_FILE}")
n=\$((n+1)); echo "\$n" > "\${COUNT_FILE}"
# succeed when n > fail_count
if (( n > ${fail_count} )); then exit 0; else exit 22; fi
EOF
    chmod +x "$tmp/curl"
    export PATH="$tmp:$PATH"
}

# Setup common test environment
setup_test_env() {
    export GOODMEM_TEST_SOURCING=1
    # Prevent any external commands from running
    export BATS_TEST_TMPDIR
    # Clear any existing database config
    unset DB_URL_DSN DB_URL_JDBC DB_HOST DB_PORT DB_USER DB_PASSWORD DB_NAME DB_SSL_MODE USE_REMOTE_DB
    # Set defaults
    export USE_REMOTE_DB=false
    export DB_PORT="5432"
    export DB_SSL_MODE="verify-full"
    
    # Add basic commands that bats might need
    local tmp="$BATS_TEST_TMPDIR/fakebin"
    mkdir -p "$tmp"
    cat > "$tmp/rm" <<'EOF'
#!/usr/bin/env bash
# Fake rm command for tests
/bin/rm "$@"
EOF
    chmod +x "$tmp/rm"
    export PATH="$tmp:$PATH"
}

# Mock TCP connectivity success
mock_tcp_connectivity_success() {
    export GOODMEM_TEST=1
    export GOODMEM_TCP_MOCK=success
}

# Mock TCP connectivity failure
mock_tcp_connectivity_failure() {
    export GOODMEM_TEST=1
    export GOODMEM_TCP_MOCK=fail
}

# Create fake docker with successful behavior (all operations succeed)
make_fake_docker_with_successful_behavior() {
    local tmp="$BATS_TEST_TMPDIR/fakebin"
    mkdir -p "$tmp"
    cat > "$tmp/docker" <<'EOF'
#!/usr/bin/env bash
if [[ "$1" == "image" && "$2" == "inspect" ]]; then
    # Image already exists (skip pull)
    exit 0
elif [[ "$1" == "pull" ]]; then
    # Pull succeeds
    exit 0
elif [[ "$1" == "run" ]]; then
    # Simulate successful psql commands
    if [[ "$*" == *"SELECT 1"* ]]; then
        echo "1"  # Connectivity test
        exit 0
    elif [[ "$*" == *"SELECT version()"* ]]; then
        echo "PostgreSQL 17.0"  # Version check
        exit 0
    elif [[ "$*" == *"SELECT extname FROM pg_extension"* ]]; then
        echo "vector"  # Extension check
        exit 0
    elif [[ "$*" == *"CREATE SCHEMA"* ]]; then
        # Schema creation test
        exit 0
    fi
    exit 0
fi
# Default success for any other docker commands
exit 0
EOF
    chmod +x "$tmp/docker"
    export PATH="$tmp:$PATH"
}

# Create fake docker where Docker Hub is blocked but GCP mirror works
make_fake_docker_with_hub_blocked() {
    local tmp="$BATS_TEST_TMPDIR/fakebin"
    mkdir -p "$tmp"
    cat > "$tmp/docker" <<'EOF'
#!/usr/bin/env bash
if [[ "$1" == "image" && "$2" == "inspect" ]]; then
    # Image doesn't exist (need to pull)
    exit 1
elif [[ "$1" == "pull" ]]; then
    if [[ "$*" == *"mirror.gcr.io"* ]]; then
        # Mirror pull fails
        exit 1
    elif [[ "$*" == *"postgres:17"* ]]; then
        # Docker Hub pull succeeds
        exit 0
    fi
    exit 1
elif [[ "$1" == "run" ]]; then
    # Simulate successful psql commands after successful pull
    if [[ "$*" == *"SELECT 1"* ]]; then
        echo "1"
        exit 0
    fi
    exit 0
fi
exit 0
EOF
    chmod +x "$tmp/docker"
    export PATH="$tmp:$PATH"
}

# Create fake docker where all image sources are blocked
make_fake_docker_with_all_pulls_blocked() {
    local tmp="$BATS_TEST_TMPDIR/fakebin"
    mkdir -p "$tmp"
    cat > "$tmp/docker" <<'EOF'
#!/usr/bin/env bash
if [[ "$1" == "image" && "$2" == "inspect" ]]; then
    # Image doesn't exist
    exit 1
elif [[ "$1" == "pull" ]]; then
    # All pulls fail (blocked)
    exit 1
fi
exit 0
EOF
    chmod +x "$tmp/docker"
    export PATH="$tmp:$PATH"
}

# Create fake docker with run failure (image pull works, but container fails)
make_fake_docker_with_run_failure() {
    local tmp="$BATS_TEST_TMPDIR/fakebin"
    mkdir -p "$tmp"
    cat > "$tmp/docker" <<'EOF'
#!/usr/bin/env bash
if [[ "$1" == "image" && "$2" == "inspect" ]]; then
    # Image exists
    exit 0
elif [[ "$1" == "pull" ]]; then
    # Pull succeeds
    exit 0
elif [[ "$1" == "run" ]]; then
    # Docker run fails
    echo "docker run failed: unable to start container"
    exit 125
fi
exit 0
EOF
    chmod +x "$tmp/docker"
    export PATH="$tmp:$PATH"
}

# Create fake docker that tracks which image is being used
make_fake_docker_with_image_tracking() {
    local tmp="$BATS_TEST_TMPDIR/fakebin"
    mkdir -p "$tmp"
    cat > "$tmp/docker" <<'EOF'
#!/usr/bin/env bash
if [[ "$1" == "image" && "$2" == "inspect" ]]; then
    if [[ "$*" == *"mirror.gcr.io"* ]]; then
        # Mirror image exists
        exit 0
    fi
    exit 1
elif [[ "$1" == "run" ]]; then
    # Track which image is being used
    if [[ "$*" == *"mirror.gcr.io"* ]]; then
        echo "Using mirror.gcr.io image" >&2
    elif [[ "$*" == *"postgres:17"* ]]; then
        echo "Using postgres:17 image" >&2
    fi
    # Simulate successful psql commands
    if [[ "$*" == *"SELECT 1"* ]]; then
        echo "1"
        exit 0
    elif [[ "$*" == *"SELECT version()"* ]]; then
        echo "PostgreSQL 17.0"
        exit 0
    elif [[ "$*" == *"SELECT extname FROM pg_extension"* ]]; then
        echo "vector"
        exit 0
    elif [[ "$*" == *"CREATE SCHEMA"* ]]; then
        exit 0
    fi
    exit 0
fi
exit 0
EOF
    chmod +x "$tmp/docker"
    export PATH="$tmp:$PATH"
}

# Create fake psql that simulates connection error
make_fake_psql_with_connection_error() {
    # This is handled by the docker mock since psql runs inside docker
    local tmp="$BATS_TEST_TMPDIR/fakebin"
    mkdir -p "$tmp"
    cat > "$tmp/docker" <<'EOF'
#!/usr/bin/env bash
if [[ "$1" == "image" && "$2" == "inspect" ]]; then
    exit 0
elif [[ "$1" == "run" ]]; then
    if [[ "$*" == *"SELECT 1"* ]]; then
        echo "psql: error: connection to server failed: Connection refused" >&2
        exit 2
    fi
    exit 0
fi
exit 0
EOF
    chmod +x "$tmp/docker"
    export PATH="$tmp:$PATH"
}

# Create fake psql that includes password in error (for redaction testing)
make_fake_psql_with_password_in_error() {
    local tmp="$BATS_TEST_TMPDIR/fakebin"
    mkdir -p "$tmp"
    cat > "$tmp/docker" <<'EOF'
#!/usr/bin/env bash
if [[ "$1" == "run" ]]; then
    if [[ "$*" == *"SELECT 1"* ]]; then
        echo "psql: error: authentication failed for user testpass" >&2
        exit 2
    fi
fi
exit 0
EOF
    chmod +x "$tmp/docker"
    export PATH="$tmp:$PATH"
}

# Create fake psql that fails on version check
make_fake_psql_with_version_failure() {
    local tmp="$BATS_TEST_TMPDIR/fakebin"
    mkdir -p "$tmp"
    cat > "$tmp/docker" <<'EOF'
#!/usr/bin/env bash
if [[ "$1" == "run" ]]; then
    if [[ "$*" == *"SELECT 1"* ]]; then
        echo "1"
        exit 0
    elif [[ "$*" == *"SELECT version()"* ]]; then
        echo "psql: error: server version check failed" >&2
        exit 1
    elif [[ "$*" == *"CREATE SCHEMA"* ]]; then
        exit 0
    fi
fi
exit 0
EOF
    chmod +x "$tmp/docker"
    export PATH="$tmp:$PATH"
}

# Create fake psql without pgvector extension
make_fake_psql_without_pgvector() {
    local tmp="$BATS_TEST_TMPDIR/fakebin"
    mkdir -p "$tmp"
    cat > "$tmp/docker" <<'EOF'
#!/usr/bin/env bash
if [[ "$1" == "run" ]]; then
    if [[ "$*" == *"SELECT 1"* ]]; then
        echo "1"
        exit 0
    elif [[ "$*" == *"SELECT version()"* ]]; then
        echo "PostgreSQL 17.0"
        exit 0
    elif [[ "$*" == *"SELECT extname FROM pg_extension"* ]]; then
        # No pgvector extension found
        echo ""
        exit 0
    elif [[ "$*" == *"CREATE SCHEMA"* ]]; then
        exit 0
    fi
fi
exit 0
EOF
    chmod +x "$tmp/docker"
    export PATH="$tmp:$PATH"
}

# Create fake psql that fails on permission check
make_fake_psql_with_permission_failure() {
    local tmp="$BATS_TEST_TMPDIR/fakebin"
    mkdir -p "$tmp"
    cat > "$tmp/docker" <<'EOF'
#!/usr/bin/env bash
if [[ "$1" == "run" ]]; then
    if [[ "$*" == *"SELECT 1"* ]]; then
        echo "1"
        exit 0
    elif [[ "$*" == *"SELECT version()"* ]]; then
        echo "PostgreSQL 17.0"
        exit 0
    elif [[ "$*" == *"SELECT extname FROM pg_extension"* ]]; then
        echo "vector"
        exit 0
    elif [[ "$*" == *"CREATE SCHEMA"* ]]; then
        echo "ERROR: permission denied to create schema" >&2
        exit 1
    fi
fi
exit 0
EOF
    chmod +x "$tmp/docker"
    export PATH="$tmp:$PATH"
}
