#!/bin/bash
#
# Test Suite for Helm Chart Generator
# Validates that all chart templates generate correctly
#

set -e

# Colors
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m'

print_info() { echo -e "${BLUE}ℹ${NC} $1"; }
print_success() { echo -e "${GREEN}✓${NC} $1"; }
print_warning() { echo -e "${YELLOW}⚠${NC} $1"; }
print_error() { echo -e "${RED}✗${NC} $1"; }

# Test counters
TESTS_RUN=0
TESTS_PASSED=0
TESTS_FAILED=0

# Test directory
TEST_DIR="$(mktemp -d)"
trap "rm -rf $TEST_DIR" EXIT

# Script locations
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PARENT_DIR="$(dirname "$SCRIPT_DIR")"
GENERATOR="$PARENT_DIR/scripts/generate-helm-chart.sh"
VALIDATOR="$PARENT_DIR/scripts/validate-helm-chart.sh"
TEMPLATES_DIR="$PARENT_DIR/templates"

echo
echo "========================================"
echo "  Helm Chart Generator Test Suite"
echo "========================================"
echo

# Test 1: Scripts exist and are executable
test_scripts_exist() {
    ((TESTS_RUN++))
    print_info "Test 1: Checking scripts exist and are executable..."

    if [[ ! -x "$GENERATOR" ]]; then
        print_error "Generator script not found or not executable: $GENERATOR"
        ((TESTS_FAILED++))
        return 1
    fi

    if [[ ! -x "$VALIDATOR" ]]; then
        print_error "Validator script not found or not executable: $VALIDATOR"
        ((TESTS_FAILED++))
        return 1
    fi

    print_success "Scripts exist and are executable"
    ((TESTS_PASSED++))
}

# Test 2: All template directories exist
test_templates_exist() {
    ((TESTS_RUN++))
    print_info "Test 2: Checking template directories..."

    REQUIRED_TEMPLATES=(
        "web-application"
        "stateful-application"
        "microservice"
        "cronjob"
        "redis"
    )

    for template in "${REQUIRED_TEMPLATES[@]}"; do
        if [[ ! -d "$TEMPLATES_DIR/$template" ]]; then
            print_error "Template directory not found: $template"
            ((TESTS_FAILED++))
            return 1
        fi

        if [[ ! -f "$TEMPLATES_DIR/$template/Chart.yaml" ]]; then
            print_error "Chart.yaml not found in $template"
            ((TESTS_FAILED++))
            return 1
        fi

        if [[ ! -f "$TEMPLATES_DIR/$template/values.yaml" ]]; then
            print_error "values.yaml not found in $template"
            ((TESTS_FAILED++))
            return 1
        fi
    done

    print_success "All template directories exist with required files"
    ((TESTS_PASSED++))
}

# Test 3: Generate each chart type
test_chart_generation() {
    local chart_type=$1
    ((TESTS_RUN++))
    print_info "Test 3.$chart_type: Generating $chart_type chart..."

    local chart_name="test-$chart_type"
    local output_path="$TEST_DIR/$chart_name"

    if ! "$GENERATOR" -t "$chart_type" -n "$chart_name" -o "$TEST_DIR" > /dev/null 2>&1; then
        print_error "Failed to generate $chart_type chart"
        ((TESTS_FAILED++))
        return 1
    fi

    if [[ ! -d "$output_path" ]]; then
        print_error "Output directory not created for $chart_type"
        ((TESTS_FAILED++))
        return 1
    fi

    if [[ ! -f "$output_path/Chart.yaml" ]]; then
        print_error "Chart.yaml not created for $chart_type"
        ((TESTS_FAILED++))
        return 1
    fi

    print_success "$chart_type chart generated successfully"
    ((TESTS_PASSED++))
}

# Test 4: Validate Chart.yaml content
test_chart_yaml() {
    local chart_type=$1
    ((TESTS_RUN++))
    print_info "Test 4.$chart_type: Validating Chart.yaml for $chart_type..."

    local chart_path="$TEST_DIR/test-$chart_type/Chart.yaml"

    # Check API version
    if ! grep -q "apiVersion: v2" "$chart_path"; then
        print_error "Chart.yaml missing apiVersion: v2 for $chart_type"
        ((TESTS_FAILED++))
        return 1
    fi

    # Check name field
    if ! grep -q "^name:" "$chart_path"; then
        print_error "Chart.yaml missing name field for $chart_type"
        ((TESTS_FAILED++))
        return 1
    fi

    # Check version field
    if ! grep -q "^version:" "$chart_path"; then
        print_error "Chart.yaml missing version field for $chart_type"
        ((TESTS_FAILED++))
        return 1
    fi

    print_success "Chart.yaml valid for $chart_type"
    ((TESTS_PASSED++))
}

# Test 5: Validate values.yaml syntax
test_values_yaml() {
    local chart_type=$1
    ((TESTS_RUN++))
    print_info "Test 5.$chart_type: Validating values.yaml for $chart_type..."

    local values_path="$TEST_DIR/test-$chart_type/values.yaml"

    # Check file exists and is not empty
    if [[ ! -s "$values_path" ]]; then
        print_error "values.yaml is empty or missing for $chart_type"
        ((TESTS_FAILED++))
        return 1
    fi

    # Try to parse with Python if available
    if command -v python3 &> /dev/null; then
        if ! python3 -c "import yaml; yaml.safe_load(open('$values_path'))" 2>/dev/null; then
            print_error "values.yaml has invalid YAML syntax for $chart_type"
            ((TESTS_FAILED++))
            return 1
        fi
    fi

    print_success "values.yaml valid for $chart_type"
    ((TESTS_PASSED++))
}

# Test 6: Check for _helpers.tpl
test_helpers() {
    local chart_type=$1
    ((TESTS_RUN++))
    print_info "Test 6.$chart_type: Checking _helpers.tpl for $chart_type..."

    local helpers_path="$TEST_DIR/test-$chart_type/templates/_helpers.tpl"

    if [[ ! -f "$helpers_path" ]]; then
        print_error "_helpers.tpl not found for $chart_type"
        ((TESTS_FAILED++))
        return 1
    fi

    # Check for common helper templates
    if ! grep -q "define.*\.name" "$helpers_path"; then
        print_warning "_helpers.tpl missing .name template for $chart_type"
    fi

    if ! grep -q "define.*\.fullname" "$helpers_path"; then
        print_warning "_helpers.tpl missing .fullname template for $chart_type"
    fi

    print_success "_helpers.tpl exists for $chart_type"
    ((TESTS_PASSED++))
}

# Test 7: Check for security contexts
test_security_contexts() {
    local chart_type=$1
    ((TESTS_RUN++))
    print_info "Test 7.$chart_type: Checking security contexts for $chart_type..."

    local templates_dir="$TEST_DIR/test-$chart_type/templates"

    if ! grep -r "securityContext" "$templates_dir" > /dev/null 2>&1; then
        print_warning "No security contexts found in $chart_type templates"
        ((TESTS_PASSED++))  # Warning, not failure
        return 0
    fi

    print_success "Security contexts found for $chart_type"
    ((TESTS_PASSED++))
}

# Test 8: Helm lint (if Helm is installed)
test_helm_lint() {
    local chart_type=$1

    if ! command -v helm &> /dev/null; then
        print_info "Helm not installed, skipping lint test for $chart_type"
        return 0
    fi

    ((TESTS_RUN++))
    print_info "Test 8.$chart_type: Running helm lint for $chart_type..."

    local chart_path="$TEST_DIR/test-$chart_type"

    if ! helm lint "$chart_path" > /dev/null 2>&1; then
        print_error "Helm lint failed for $chart_type"
        ((TESTS_FAILED++))
        return 1
    fi

    print_success "Helm lint passed for $chart_type"
    ((TESTS_PASSED++))
}

# Test 9: Helm template rendering (if Helm is installed)
test_helm_template() {
    local chart_type=$1

    if ! command -v helm &> /dev/null; then
        print_info "Helm not installed, skipping template test for $chart_type"
        return 0
    fi

    ((TESTS_RUN++))
    print_info "Test 9.$chart_type: Testing template rendering for $chart_type..."

    local chart_path="$TEST_DIR/test-$chart_type"

    if ! helm template test "$chart_path" > /dev/null 2>&1; then
        print_error "Template rendering failed for $chart_type"
        ((TESTS_FAILED++))
        return 1
    fi

    print_success "Template rendering successful for $chart_type"
    ((TESTS_PASSED++))
}

# Run all tests
echo
print_info "Running test suite..."
echo

# Basic tests
test_scripts_exist
test_templates_exist

# Test each chart type
CHART_TYPES=("web-application" "stateful-application" "microservice" "cronjob" "redis")

for chart_type in "${CHART_TYPES[@]}"; do
    echo
    print_info "Testing chart type: $chart_type"
    echo

    test_chart_generation "$chart_type"
    test_chart_yaml "$chart_type"
    test_values_yaml "$chart_type"
    test_helpers "$chart_type"
    test_security_contexts "$chart_type"
    test_helm_lint "$chart_type"
    test_helm_template "$chart_type"
done

# Summary
echo
echo "========================================"
echo "  Test Summary"
echo "========================================"
echo
echo "Total tests run:    $TESTS_RUN"
print_success "Tests passed:     $TESTS_PASSED"
if [[ $TESTS_FAILED -gt 0 ]]; then
    print_error "Tests failed:     $TESTS_FAILED"
else
    print_success "Tests failed:     $TESTS_FAILED"
fi
echo

if [[ $TESTS_FAILED -eq 0 ]]; then
    print_success "All tests passed!"
    echo
    print_info "Chart generator is working correctly"
    exit 0
else
    print_error "Some tests failed"
    echo
    print_info "Please review the errors above"
    exit 1
fi
