#!/bin/bash
#
# Helm Chart Validator - Validates Helm charts for syntax and best practices
#
# Usage: ./validate-helm-chart.sh [chart-path]
#

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"; }

# Parse arguments
CHART_PATH="${1:-.}"

if [[ ! -d "$CHART_PATH" ]]; then
    print_error "Chart directory not found: $CHART_PATH"
    exit 1
fi

if [[ ! -f "$CHART_PATH/Chart.yaml" ]]; then
    print_error "Not a valid Helm chart: Chart.yaml not found in $CHART_PATH"
    exit 1
fi

echo
print_info "Validating Helm chart: $CHART_PATH"
echo

# Check if helm is installed
if ! command -v helm &> /dev/null; then
    print_error "Helm is not installed. Please install Helm first."
    echo "  Visit: https://helm.sh/docs/intro/install/"
    exit 1
fi

ERRORS=0
WARNINGS=0

# 1. Helm Lint
print_info "Running helm lint..."
if helm lint "$CHART_PATH" --strict; then
    print_success "Lint check passed"
else
    print_error "Lint check failed"
    ((ERRORS++))
fi
echo

# 2. Helm Template Rendering
print_info "Testing template rendering..."
if helm template test "$CHART_PATH" > /dev/null 2>&1; then
    print_success "Template rendering successful"
else
    print_error "Template rendering failed"
    ((ERRORS++))
fi
echo

# 3. Check Chart.yaml required fields
print_info "Checking Chart.yaml..."
CHART_NAME=$(grep "^name:" "$CHART_PATH/Chart.yaml" | awk '{print $2}')
CHART_VERSION=$(grep "^version:" "$CHART_PATH/Chart.yaml" | awk '{print $2}')
CHART_API_VERSION=$(grep "^apiVersion:" "$CHART_PATH/Chart.yaml" | awk '{print $2}')

if [[ -z "$CHART_NAME" ]]; then
    print_error "Chart.yaml missing 'name' field"
    ((ERRORS++))
else
    print_success "Chart name: $CHART_NAME"
fi

if [[ -z "$CHART_VERSION" ]]; then
    print_error "Chart.yaml missing 'version' field"
    ((ERRORS++))
else
    print_success "Chart version: $CHART_VERSION"
fi

if [[ "$CHART_API_VERSION" != "v2" ]]; then
    print_warning "Chart apiVersion should be 'v2' for Helm 3"
    ((WARNINGS++))
fi
echo

# 4. Check required files
print_info "Checking required files..."
REQUIRED_FILES=("Chart.yaml" "values.yaml" "templates/_helpers.tpl")

for file in "${REQUIRED_FILES[@]}"; do
    if [[ -f "$CHART_PATH/$file" ]]; then
        print_success "Found: $file"
    else
        print_warning "Missing recommended file: $file"
        ((WARNINGS++))
    fi
done
echo

# 5. Check for security contexts
print_info "Checking security contexts..."
if grep -r "securityContext" "$CHART_PATH/templates/" > /dev/null 2>&1; then
    print_success "Security contexts found"
else
    print_warning "No security contexts defined in templates"
    ((WARNINGS++))
fi
echo

# 6. Check for resource limits
print_info "Checking resource limits..."
if grep -r "resources:" "$CHART_PATH/templates/" > /dev/null 2>&1; then
    print_success "Resource limits/requests found"
else
    print_warning "No resource limits defined in templates"
    ((WARNINGS++))
fi
echo

# 7. Check for health probes
print_info "Checking health probes..."
PROBES_FOUND=0
if grep -r "livenessProbe" "$CHART_PATH/templates/" > /dev/null 2>&1; then
    ((PROBES_FOUND++))
fi
if grep -r "readinessProbe" "$CHART_PATH/templates/" > /dev/null 2>&1; then
    ((PROBES_FOUND++))
fi

if [[ $PROBES_FOUND -ge 2 ]]; then
    print_success "Health probes configured"
elif [[ $PROBES_FOUND -eq 1 ]]; then
    print_warning "Only one type of health probe found"
    ((WARNINGS++))
else
    print_warning "No health probes found"
    ((WARNINGS++))
fi
echo

# 8. Check YAML syntax in values.yaml
print_info "Validating values.yaml syntax..."
if command -v yamllint &> /dev/null; then
    if yamllint "$CHART_PATH/values.yaml" > /dev/null 2>&1; then
        print_success "values.yaml syntax valid"
    else
        print_error "values.yaml syntax errors"
        ((ERRORS++))
    fi
else
    print_info "yamllint not installed, skipping YAML validation"
fi
echo

# 9. Template rendering with different values
print_info "Testing template with different values..."
TEST_VALUES=$(mktemp)
cat > "$TEST_VALUES" << EOF
replicaCount: 1
resources:
  limits:
    cpu: 100m
    memory: 128Mi
EOF

if helm template test "$CHART_PATH" -f "$TEST_VALUES" > /dev/null 2>&1; then
    print_success "Template rendering with custom values successful"
else
    print_warning "Template rendering with custom values failed"
    ((WARNINGS++))
fi
rm -f "$TEST_VALUES"
echo

# Summary
echo "================================"
echo "Validation Summary"
echo "================================"
echo
if [[ $ERRORS -eq 0 ]]; then
    print_success "No errors found"
else
    print_error "$ERRORS error(s) found"
fi

if [[ $WARNINGS -eq 0 ]]; then
    print_success "No warnings"
else
    print_warning "$WARNINGS warning(s) found"
fi

echo
if [[ $ERRORS -eq 0 ]]; then
    print_success "Chart validation passed!"
    echo
    print_info "Chart is ready to be deployed"
    print_info "To install: helm install <release-name> $CHART_PATH"
    exit 0
else
    print_error "Chart validation failed"
    echo
    print_info "Please fix the errors above before deploying"
    exit 1
fi
