#!/bin/bash

# Test script for GitLab CI/CD configurations
# Validates all template configurations for syntax and best practices

set -e

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

# Script directory
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
TEMPLATES_DIR="$(dirname "$SCRIPT_DIR")/templates"
VALIDATOR="$(dirname "$SCRIPT_DIR")/scripts/validate-gitlab-ci.sh"

echo -e "${BLUE}========================================${NC}"
echo -e "${BLUE}GitLab CI/CD Template Tests${NC}"
echo -e "${BLUE}========================================${NC}"
echo ""

# Counter
TOTAL_TESTS=0
PASSED_TESTS=0
FAILED_TESTS=0

# Function to run test
run_test() {
    local test_name=$1
    local test_command=$2

    ((TOTAL_TESTS++))
    echo -n "Testing: $test_name ... "

    if eval "$test_command" > /dev/null 2>&1; then
        echo -e "${GREEN}✓ PASS${NC}"
        ((PASSED_TESTS++))
        return 0
    else
        echo -e "${RED}✗ FAIL${NC}"
        ((FAILED_TESTS++))
        return 1
    fi
}

# Function to test YAML syntax
test_yaml_syntax() {
    local file=$1
    python3 -c "import yaml; yaml.safe_load(open('$file'))" 2>/dev/null
}

# Function to check for required fields
test_required_fields() {
    local file=$1
    local field=$2
    grep -q "$field" "$file"
}

# Function to check for security issues
test_security() {
    local file=$1
    # Check for hardcoded secrets
    ! grep -iE "(password|secret|token|api_key).*[:=].*['\"]" "$file" | grep -v "\$CI_" | grep -v "\$\{" > /dev/null 2>&1
}

echo -e "${BLUE}1. Testing YAML Syntax${NC}"
echo ""

for template_dir in "$TEMPLATES_DIR"/*; do
    if [ -d "$template_dir" ]; then
        template_name=$(basename "$template_dir")
        config_file="$template_dir/.gitlab-ci.yml"

        if [ -f "$config_file" ]; then
            run_test "YAML syntax: $template_name" "test_yaml_syntax '$config_file'"
        fi
    fi
done
echo ""

echo -e "${BLUE}2. Testing Required Fields${NC}"
echo ""

for template_dir in "$TEMPLATES_DIR"/*; do
    if [ -d "$template_dir" ]; then
        template_name=$(basename "$template_dir")
        config_file="$template_dir/.gitlab-ci.yml"

        if [ -f "$config_file" ]; then
            # Test for stages or jobs
            run_test "Has stages or jobs: $template_name" "test_required_fields '$config_file' '^stages:' || grep -q '^[a-zA-Z0-9_-]*:' '$config_file'"

            # Test for script commands
            run_test "Has script commands: $template_name" "test_required_fields '$config_file' 'script:'"
        fi
    fi
done
echo ""

echo -e "${BLUE}3. Testing Security Best Practices${NC}"
echo ""

for template_dir in "$TEMPLATES_DIR"/*; do
    if [ -d "$template_dir" ]; then
        template_name=$(basename "$template_dir")
        config_file="$template_dir/.gitlab-ci.yml"

        if [ -f "$config_file" ]; then
            run_test "No hardcoded secrets: $template_name" "test_security '$config_file'"
        fi
    fi
done
echo ""

echo -e "${BLUE}4. Testing Performance Optimizations${NC}"
echo ""

for template_dir in "$TEMPLATES_DIR"/*; do
    if [ -d "$template_dir" ]; then
        template_name=$(basename "$template_dir")
        config_file="$template_dir/.gitlab-ci.yml"

        if [ -f "$config_file" ]; then
            # Check for FastZip
            if grep -q "FF_USE_FASTZIP" "$config_file"; then
                run_test "FastZip enabled: $template_name" "true"
            else
                ((TOTAL_TESTS++))
                echo -e "Testing: FastZip enabled: $template_name ... ${YELLOW}⚠ SKIP (optional)${NC}"
            fi

            # Check for caching
            if grep -q "cache:" "$config_file"; then
                run_test "Caching configured: $template_name" "true"
            else
                ((TOTAL_TESTS++))
                echo -e "Testing: Caching configured: $template_name ... ${YELLOW}⚠ SKIP (not applicable)${NC}"
            fi
        fi
    fi
done
echo ""

echo -e "${BLUE}5. Testing Node.js Template Specifics${NC}"
echo ""

NODE_TEMPLATE="$TEMPLATES_DIR/node-ci-cd/.gitlab-ci.yml"
if [ -f "$NODE_TEMPLATE" ]; then
    run_test "Node.js: Has npm caching" "grep -q 'npm_config_cache' '$NODE_TEMPLATE'"
    run_test "Node.js: Has test stage" "grep -q 'test.*:' '$NODE_TEMPLATE'"
    run_test "Node.js: Has lint job" "grep -q 'lint:' '$NODE_TEMPLATE'"
    run_test "Node.js: Has build job" "grep -q 'build.*:' '$NODE_TEMPLATE'"
else
    echo -e "${YELLOW}Node.js template not found${NC}"
fi
echo ""

echo -e "${BLUE}6. Testing Python Template Specifics${NC}"
echo ""

PYTHON_TEMPLATE="$TEMPLATES_DIR/python-ci-cd/.gitlab-ci.yml"
if [ -f "$PYTHON_TEMPLATE" ]; then
    run_test "Python: Has venv configuration" "grep -q 'VENV_PATH' '$PYTHON_TEMPLATE'"
    run_test "Python: Has pytest" "grep -q 'pytest' '$PYTHON_TEMPLATE'"
    run_test "Python: Has coverage" "grep -q 'coverage' '$PYTHON_TEMPLATE'"
    run_test "Python: Has security scanning" "grep -q 'bandit' '$PYTHON_TEMPLATE' || grep -q 'safety' '$PYTHON_TEMPLATE'"
else
    echo -e "${YELLOW}Python template not found${NC}"
fi
echo ""

echo -e "${BLUE}7. Testing Docker Template Specifics${NC}"
echo ""

DOCKER_TEMPLATE="$TEMPLATES_DIR/docker-build-push/.gitlab-ci.yml"
if [ -f "$DOCKER_TEMPLATE" ]; then
    run_test "Docker: Has Docker-in-Docker" "grep -q 'docker:.*-dind' '$DOCKER_TEMPLATE'"
    run_test "Docker: Has TLS configuration" "grep -q 'DOCKER_TLS_CERTDIR' '$DOCKER_TEMPLATE'"
    run_test "Docker: Has image scanning" "grep -q 'trivy' '$DOCKER_TEMPLATE' || grep -q 'container_scanning' '$DOCKER_TEMPLATE'"
    run_test "Docker: Has multi-stage build" "grep -q 'cache-from' '$DOCKER_TEMPLATE'"
else
    echo -e "${YELLOW}Docker template not found${NC}"
fi
echo ""

echo -e "${BLUE}8. Testing Kubernetes Template Specifics${NC}"
echo ""

K8S_TEMPLATE="$TEMPLATES_DIR/kubernetes-deploy/.gitlab-ci.yml"
if [ -f "$K8S_TEMPLATE" ]; then
    run_test "K8s: Has kubectl image" "grep -q 'kubectl' '$K8S_TEMPLATE'"
    run_test "K8s: Has namespace creation" "grep -q 'create namespace' '$K8S_TEMPLATE'"
    run_test "K8s: Has rollout status check" "grep -q 'rollout status' '$K8S_TEMPLATE'"
    run_test "K8s: Has rollback job" "grep -q 'rollback' '$K8S_TEMPLATE'"
else
    echo -e "${YELLOW}Kubernetes template not found${NC}"
fi
echo ""

echo -e "${BLUE}9. Testing Security Scanning Template${NC}"
echo ""

SECURITY_TEMPLATE="$TEMPLATES_DIR/security-scanning/.gitlab-ci.yml"
if [ -f "$SECURITY_TEMPLATE" ]; then
    run_test "Security: Has SAST" "grep -q 'SAST' '$SECURITY_TEMPLATE'"
    run_test "Security: Has dependency scanning" "grep -q 'Dependency-Scanning' '$SECURITY_TEMPLATE' || grep -q 'dependency' '$SECURITY_TEMPLATE'"
    run_test "Security: Has secret detection" "grep -q 'Secret-Detection' '$SECURITY_TEMPLATE' || grep -q 'secret' '$SECURITY_TEMPLATE'"
    run_test "Security: Has container scanning" "grep -q 'Container-Scanning' '$SECURITY_TEMPLATE' || grep -q 'trivy' '$SECURITY_TEMPLATE'"
else
    echo -e "${YELLOW}Security scanning template not found${NC}"
fi
echo ""

echo -e "${BLUE}10. Testing Go Template Specifics${NC}"
echo ""

GO_TEMPLATE="$TEMPLATES_DIR/go-ci-cd/.gitlab-ci.yml"
if [ -f "$GO_TEMPLATE" ]; then
    run_test "Go: Has Go modules cache" "grep -q 'GOMODCACHE' '$GO_TEMPLATE' || grep -q 'go.mod' '$GO_TEMPLATE'"
    run_test "Go: Has go test" "grep -q 'go test' '$GO_TEMPLATE'"
    run_test "Go: Has linting" "grep -q 'golangci-lint' '$GO_TEMPLATE' || grep -q 'go vet' '$GO_TEMPLATE'"
    run_test "Go: Has multi-platform build" "grep -q 'GOOS' '$GO_TEMPLATE' && grep -q 'GOARCH' '$GO_TEMPLATE'"
else
    echo -e "${YELLOW}Go template not found${NC}"
fi
echo ""

echo -e "${BLUE}11. Testing Common Best Practices${NC}"
echo ""

for template_dir in "$TEMPLATES_DIR"/*; do
    if [ -d "$template_dir" ]; then
        template_name=$(basename "$template_dir")
        config_file="$template_dir/.gitlab-ci.yml"

        if [ -f "$config_file" ]; then
            # Check for environment configuration
            if grep -q "environment:" "$config_file"; then
                run_test "Has environment URL: $template_name" "grep -A 2 'environment:' '$config_file' | grep -q 'url:' || true"
            fi

            # Check for manual deployment to production
            if grep -q "production" "$config_file"; then
                # This is optional, so we just check
                if grep -B 5 "production" "$config_file" | grep -q "when: manual"; then
                    run_test "Production requires manual approval: $template_name" "true"
                else
                    ((TOTAL_TESTS++))
                    echo -e "Testing: Production requires manual approval: $template_name ... ${YELLOW}⚠ OPTIONAL${NC}"
                fi
            fi
        fi
    fi
done
echo ""

echo -e "${BLUE}12. Testing File Structure${NC}"
echo ""

# Check that all expected templates exist
EXPECTED_TEMPLATES=("node-ci-cd" "python-ci-cd" "docker-build-push" "kubernetes-deploy" "security-scanning" "go-ci-cd")

for template in "${EXPECTED_TEMPLATES[@]}"; do
    run_test "Template exists: $template" "test -f '$TEMPLATES_DIR/$template/.gitlab-ci.yml'"
done
echo ""

# Summary
echo -e "${BLUE}========================================${NC}"
echo -e "${BLUE}Test Summary${NC}"
echo -e "${BLUE}========================================${NC}"
echo ""
echo -e "Total Tests:  $TOTAL_TESTS"
echo -e "${GREEN}Passed Tests: $PASSED_TESTS${NC}"
if [ $FAILED_TESTS -gt 0 ]; then
    echo -e "${RED}Failed Tests: $FAILED_TESTS${NC}"
else
    echo -e "${GREEN}Failed Tests: $FAILED_TESTS${NC}"
fi
echo ""

if [ $FAILED_TESTS -eq 0 ]; then
    echo -e "${GREEN}========================================${NC}"
    echo -e "${GREEN}All tests passed! ✓${NC}"
    echo -e "${GREEN}========================================${NC}"
    exit 0
else
    echo -e "${RED}========================================${NC}"
    echo -e "${RED}Some tests failed! ✗${NC}"
    echo -e "${RED}========================================${NC}"
    exit 1
fi
