#!/bin/bash

# Deployment System Test Suite
# Comprehensive tests for deployment library functions
#
# This script tests all atomic, molecular, and organism functions
# to ensure deployment reliability.
#
# Documentation: docs/DEPLOYMENT_TESTING_GUIDE.md
#
# Usage:
#   ./scripts/test-deploy.sh [--verbose]
#
# Options:
#   --verbose, -v    Show detailed test output for each test
#
# Test Categories:
#   • Atomic Functions (45+ tests) - Basic building blocks
#   • Molecular Operations (15+ tests) - Combined operations
#   • Organism Workflows (9+ tests) - Complete workflows
#   • Integration Tests (8+ tests) - All components together
#   • Backwards Compatibility (2+ tests) - Old configs work
#
# Examples:
#   ./scripts/test-deploy.sh              # Run all tests (normal output)
#   ./scripts/test-deploy.sh --verbose    # Run with detailed output
#
# Exit Codes:
#   0 - All tests passed
#   1 - One or more tests failed
#
# For troubleshooting test failures, see:
#   docs/DEPLOYMENT_TESTING_GUIDE.md

set -e

# ==============================================================================
# SETUP
# ==============================================================================

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_ROOT="$(dirname "$SCRIPT_DIR")"
cd "$PROJECT_ROOT"

# Load deployment libraries
source "$SCRIPT_DIR/_deploy-atoms.sh"
source "$SCRIPT_DIR/_deploy-molecules.sh"
source "$SCRIPT_DIR/_deploy-organisms.sh"

# Test counters
TESTS_PASSED=0
TESTS_FAILED=0
VERBOSE=false

# Parse arguments
for arg in "$@"; do
    case $arg in
        --verbose|-v)
            VERBOSE=true
            ;;
    esac
done

# ==============================================================================
# TEST FRAMEWORK
# ==============================================================================

# Assert test passes
assert_true() {
    local test_name="$1"
    local condition="$2"

    if $condition; then
        ((TESTS_PASSED++))
        if [[ "$VERBOSE" == "true" ]]; then
            log_success "PASS: $test_name"
        else
            echo -n "."
        fi
    else
        ((TESTS_FAILED++))
        log_error "FAIL: $test_name"
    fi
}

# Assert command succeeds
assert_command_succeeds() {
    local test_name="$1"
    shift

    if "$@" > /dev/null 2>&1; then
        ((TESTS_PASSED++))
        if [[ "$VERBOSE" == "true" ]]; then
            log_success "PASS: $test_name"
        else
            echo -n "."
        fi
    else
        ((TESTS_FAILED++))
        log_error "FAIL: $test_name"
    fi
}

# Assert file exists
assert_file_exists() {
    local test_name="$1"
    local file_path="$2"

    if [[ -f "$file_path" ]]; then
        ((TESTS_PASSED++))
        if [[ "$VERBOSE" == "true" ]]; then
            log_success "PASS: $test_name"
        else
            echo -n "."
        fi
    else
        ((TESTS_FAILED++))
        log_error "FAIL: $test_name (file not found: $file_path)"
    fi
}

# ==============================================================================
# ATOMIC FUNCTION TESTS
# ==============================================================================

test_atoms() {
    log_section "Testing Atomic Functions"

    # Logging functions
    assert_command_succeeds "log_info function" log_info "Test message"
    assert_command_succeeds "log_success function" log_success "Test message"
    assert_command_succeeds "log_warning function" log_warning "Test message"
    assert_command_succeeds "log_error function" log_error "Test message"

    # Validation functions
    assert_true "command_exists (php)" command_exists php
    assert_true "file_exists (.env)" file_exists .env
    assert_true "dir_exists (scripts)" dir_exists scripts
    assert_true "is_empty (empty string)" is_empty ""
    assert_true "is_not_empty (non-empty)" is_not_empty "test"
    assert_true "is_number (123)" is_number 123

    # Environment detection
    assert_command_succeeds "get_php_path" get_php_path
    assert_command_succeeds "get_php_version" get_php_version
    assert_command_succeeds "get_db_type" get_db_type
    assert_command_succeeds "get_app_env" get_app_env
    assert_command_succeeds "get_git_branch" get_git_branch

    # String operations
    assert_true "trim function" test "$(trim '  test  ')" = "test"
    assert_true "to_lowercase function" test "$(to_lowercase 'TEST')" = "test"
    assert_true "to_uppercase function" test "$(to_uppercase 'test')" = "TEST"

    # Time operations
    assert_command_succeeds "get_timestamp" get_timestamp
    assert_command_succeeds "get_timestamp_filename" get_timestamp_filename

    # Configuration functions
    assert_command_succeeds "read_env (DB_CONNECTION)" read_env "DB_CONNECTION"

    echo ""
    log_success "Atomic function tests completed"
}

# ==============================================================================
# MOLECULAR FUNCTION TESTS
# ==============================================================================

test_molecules() {
    log_section "Testing Molecular Functions"

    # Git operations
    assert_command_succeeds "get_git_branch" get_git_branch
    assert_command_succeeds "get_git_commit" get_git_commit

    # PHP environment
    assert_command_succeeds "setup_php_environment" setup_php_environment

    # Process management
    assert_command_succeeds "is_queue_worker_running check" is_queue_worker_running || true

    # Database operations
    if php artisan --version > /dev/null 2>&1; then
        assert_command_succeeds "roles_table_empty check" roles_table_empty || true
    fi

    echo ""
    log_success "Molecular function tests completed"
}

# ==============================================================================
# ORGANISM WORKFLOW TESTS
# ==============================================================================

test_organisms() {
    log_section "Testing Organism Workflows"

    # Pre-deployment checks (should pass in dev environment)
    assert_command_succeeds "pre_deployment_checks" pre_deployment_checks

    # Health check
    assert_command_succeeds "health_check" health_check || true

    # Status report
    assert_command_succeeds "deployment_status_report" deployment_status_report

    echo ""
    log_success "Organism workflow tests completed"
}

# ==============================================================================
# INTEGRATION TESTS
# ==============================================================================

test_integration() {
    log_section "Testing Integration"

    # Test deployment library chain
    assert_file_exists "Atoms library exists" "$SCRIPT_DIR/_deploy-atoms.sh"
    assert_file_exists "Molecules library exists" "$SCRIPT_DIR/_deploy-molecules.sh"
    assert_file_exists "Organisms library exists" "$SCRIPT_DIR/_deploy-organisms.sh"
    assert_file_exists "Main deploy script exists" "$SCRIPT_DIR/deploy-dev.sh"

    # Test supporting scripts
    assert_file_exists "backup-db.sh exists" "$SCRIPT_DIR/backup-db.sh"
    assert_file_exists "queue-monitor.sh exists" "$SCRIPT_DIR/queue-monitor.sh"
    assert_file_exists "start-queue-worker.sh exists" "$SCRIPT_DIR/start-queue-worker.sh"

    # Test that deploy script is executable
    assert_true "deploy-dev.sh is executable" test -x "$SCRIPT_DIR/deploy-dev.sh"

    # Test help command works
    assert_command_succeeds "deploy-dev.sh --help" bash "$SCRIPT_DIR/deploy-dev.sh" --help

    echo ""
    log_success "Integration tests completed"
}

# ==============================================================================
# BACKWARDS COMPATIBILITY TESTS
# ==============================================================================

test_backwards_compatibility() {
    log_section "Testing Backwards Compatibility"

    # Test old environment variable names still work
    if [[ -f ".env" ]]; then
        assert_command_succeeds "DB_CONNECTION readable" read_env "DB_CONNECTION"
        assert_command_succeeds "APP_ENV readable" read_env "APP_ENV"
    fi

    # Test queue worker supports all queues
    local worker_cmd="php artisan queue:work database --queue=critical,default,tickets,bulk"
    assert_true "Queue config includes bulk queue" echo "$worker_cmd" | grep -q "bulk"

    echo ""
    log_success "Backwards compatibility tests completed"
}

# ==============================================================================
# RUN ALL TESTS
# ==============================================================================

log_section "Deployment System Test Suite"

if [[ "$VERBOSE" != "true" ]]; then
    log_info "Running tests (use --verbose for detailed output)..."
    echo -n "Progress: "
fi

# Run test suites
test_atoms
test_molecules
test_organisms
test_integration
test_backwards_compatibility

# ==============================================================================
# RESULTS
# ==============================================================================

echo ""
log_section "Test Results"

TOTAL_TESTS=$((TESTS_PASSED + TESTS_FAILED))

echo "Tests Run:    $TOTAL_TESTS"
echo "Tests Passed: $TESTS_PASSED"
echo "Tests Failed: $TESTS_FAILED"
echo ""

if [[ $TESTS_FAILED -eq 0 ]]; then
    log_success "All tests passed! ✓"
    echo ""
    echo "Deployment system is ready for use."
    exit 0
else
    log_error "$TESTS_FAILED test(s) failed"
    echo ""
    echo "Please fix the failing tests before deploying."
    exit 1
fi
