#!/bin/sh
# Gitea Initialization Script for Fellowship DevOps Escape Room
# Sets up Gitea with admin user, organization, and the LOTR SUT repository
# This script runs as a one-shot container after Gitea starts up
#
# Key: We use docker-compose exec instead of docker exec for reliable container access

set -e

GITEA_URL="${GITEA_URL:-http://gitea:3000}"
ADMIN_USER="${GITEA_ADMIN_USER:-fellowship}"
ADMIN_PASS="${GITEA_ADMIN_PASSWORD:-fellowship123}"
ADMIN_EMAIL="${GITEA_ADMIN_EMAIL:-gandalf@fellowship.local}"
ORG_NAME="${GITEA_ORG_NAME:-fellowship-org}"
REPO_NAME="${GITEA_REPO_NAME:-lotr-sut}"
REPO_DESC="The Fellowship's Quest List — LOTR-themed SUT for DevOps tutorials"
SUT_SOURCE_DIR="${SUT_SOURCE_DIR:-/sut-source}"

log() {
    echo "[$(date '+%Y-%m-%d %H:%M:%S')] [gitea-init] $*"
}

warn() {
    echo "[$(date '+%Y-%m-%d %H:%M:%S')] [gitea-init] ⚠️  WARNING: $*" >&2
}

error() {
    echo "[$(date '+%Y-%m-%d %H:%M:%S')] [gitea-init] ❌ ERROR: $*" >&2
    return 1
}

log "=========================================="
log "Gitea Initialization — Fellowship DevOps"
log "=========================================="
log "Settings:"
log "  Gitea Container: ${GITEA_CONTAINER}"
log "  Admin User: ${ADMIN_USER}"
log "  Organization: ${ORG_NAME}"
log "  Repository: ${ORG_NAME}/${REPO_NAME}"
log "=========================================="

# Install required tools
setup_tools() {
    log "Setting up tools..."
    if ! command -v curl > /dev/null 2>&1; then
        apk add --no-cache curl
    fi
    if ! command -v docker > /dev/null 2>&1; then
        apk add --no-cache docker-cli
    fi
    log "✓ Tools ready"
}

# Wait for Gitea to be ready
wait_for_gitea() {
    log "Waiting for Gitea API to be ready at ${GITEA_URL}..."
    local max_attempts=60
    local attempt=1
    while [ $attempt -le $max_attempts ]; do
        if curl -sf "${GITEA_URL}/api/v1/version" > /dev/null 2>&1; then
            log "✓ Gitea API is ready"
            return 0
        fi
        sleep 2
        attempt=$((attempt + 1))
        [ $((attempt % 10)) -eq 0 ] && log "  Still waiting (${attempt}/${max_attempts})..."
    done
    error "Gitea did not become ready after $((max_attempts * 2)) seconds"
    return 1
}

# Create the admin user using Gitea CLI via docker
create_admin() {
    log "Creating admin user '${ADMIN_USER}'..."
    
    # Check if user already exists via API
    local existing_user
    existing_user=$(curl -s -u "${ADMIN_USER}:${ADMIN_PASS}" "${GITEA_URL}/api/v1/user" 2>/dev/null || echo "")
    
    if echo "$existing_user" | grep -q '"username"'; then
        log "✓ Admin user '${ADMIN_USER}' already exists"
        return 0
    fi
    
    # Find gitea container by name matching (handles project prefix like fellowship-gitea-1)
    local gitea_container
    gitea_container=$(docker ps --format '{{.Names}}' | grep -E 'gitea$|gitea-1$|gitea-[\w-]*$' | head -1)
    
    if [ -z "$gitea_container" ]; then
        error "Could not find gitea container"
        return 1
    fi
    
    log "  Found gitea container: $gitea_container"
    
    # Use gitea CLI to create admin user via docker exec
    # Must run as 'git' user (not root) - Gitea refuses to run as root
    if docker exec -u git "$gitea_container" \
        gitea admin user create \
        --username "${ADMIN_USER}" \
        --password "${ADMIN_PASS}" \
        --email "${ADMIN_EMAIL}" \
        --admin \
        --must-change-password=false > /tmp/gitea_user_create.log 2>&1; then
        log "✓ Admin user '${ADMIN_USER}' created successfully"
        return 0
    fi
    
    # Check if user already exists (might exist from previous run)
    if grep -q "already exists" /tmp/gitea_user_create.log 2>/dev/null; then
        log "✓ Admin user '${ADMIN_USER}' already exists"
        return 0
    fi
    
    # If both methods fail, show error and return failure
    log "Creation output:"
    cat /tmp/gitea_user_create.log || true
    error "Failed to create admin user"
    return 1
}


# Create organization via API (requires auth)
create_org() {
    log "Creating organization '${ORG_NAME}'..."

    local response
    response=$(curl -s -X POST "${GITEA_URL}/api/v1/orgs" \
        -u "${ADMIN_USER}:${ADMIN_PASS}" \
        -H "Content-Type: application/json" \
        -d "{
            \"username\": \"${ORG_NAME}\",
            \"full_name\": \"The Fellowship of the Ring\",
            \"description\": \"One org to rule them all\",
            \"visibility\": \"public\"
        }" 2>&1)
    
    if echo "$response" | grep -q '"id"'; then
        log "✓ Organization '${ORG_NAME}' created"
        return 0
    elif echo "$response" | grep -q "already exists\|account already exists"; then
        log "✓ Organization '${ORG_NAME}' already exists"
        return 0
    else
        # Log the actual API response for debugging
        echo "$response" 1>&2
        error "Failed to create organization"
        return 1
    fi
}

# Create repository via API (requires auth)
create_repo() {
    log "Creating repository '${ORG_NAME}/${REPO_NAME}'..."

    local status
    status=$(curl -s -o /dev/null -w "%{http_code}" \
        -u "${ADMIN_USER}:${ADMIN_PASS}" \
        "${GITEA_URL}/api/v1/repos/${ORG_NAME}/${REPO_NAME}" 2>/dev/null)

    if [ "$status" = "200" ]; then
        log "✓ Repository '${ORG_NAME}/${REPO_NAME}' already exists"
        return 0
    fi

    local response
    response=$(curl -s -X POST "${GITEA_URL}/api/v1/orgs/${ORG_NAME}/repos" \
        -u "${ADMIN_USER}:${ADMIN_PASS}" \
        -H "Content-Type: application/json" \
        -d "{
            \"name\": \"${REPO_NAME}\",
            \"description\": \"${REPO_DESC}\",
            \"private\": false,
            \"auto_init\": false,
            \"default_branch\": \"main\"
        }" 2>&1)
    
    if echo "$response" | grep -q '"id"'; then
        log "✓ Repository '${ORG_NAME}/${REPO_NAME}' created"
        return 0
    elif echo "$response" | grep -q "already exists\|The repository already exists"; then
        log "✓ Repository '${ORG_NAME}/${REPO_NAME}' already exists"
        return 0
    else
        # Log the actual API response for debugging
        echo "$response" 1>&2
        error "Failed to create repository"
        return 1
    fi
}

# Push SUT source code to Gitea (optional, skipped if repo has commits)
push_sut_code() {
    log "Checking if SUT code needs to be pushed..."

    # Check if repo already has commits
    local commits
    commits=$(curl -s \
        -u "${ADMIN_USER}:${ADMIN_PASS}" \
        "${GITEA_URL}/api/v1/repos/${ORG_NAME}/${REPO_NAME}/commits?limit=1" \
        2>/dev/null | grep -c '"sha"' || echo "0")
    
    # Trim whitespace and handle invalid values
    commits=$(echo "$commits" | xargs)
    commits=${commits:-0}  # Default to 0 if empty
    
    # Check if commits is a valid number and greater than 0
    if [ "$commits" -gt 0 ] 2>/dev/null; then
        log "✓ Repository already has commits — skipping push"
        return 0
    fi

    # Find the SUT source
    if [ ! -d "${SUT_SOURCE_DIR}" ]; then
        warn "SUT source directory not found at ${SUT_SOURCE_DIR}"
        warn "Skipping code push — repository will be created but empty"
        return 0
    fi

    log "  Source directory: ${SUT_SOURCE_DIR}"
    log "  (Code push omitted for now — repository ready for manual commit)"
    return 0
}



# Main initialization sequence
main() {
    setup_tools || exit 1
    
    if ! wait_for_gitea; then
        error "Aborting — Gitea is not available"
        exit 1
    fi

    # Create admin user first (required for subsequent operations)
    if ! create_admin; then
        error "Failed to create admin user"
        exit 1
    fi
    
    # Wait for admin credentials to be valid before using API
    log "Waiting for admin credentials to be recognized..."
    local max_attempts=15
    local attempt=1
    while [ $attempt -le $max_attempts ]; do
        if curl -sf -u "${ADMIN_USER}:${ADMIN_PASS}" \
            "${GITEA_URL}/api/v1/user" > /dev/null 2>&1; then
            log "✓ Admin user is now authenticated"
            break
        fi
        sleep 1
        attempt=$((attempt + 1))
        [ $((attempt % 5)) -eq 0 ] && log "  Still waiting (${attempt}/${max_attempts})..."
    done
    
    # Create organization
    if ! create_org; then
        warn "Failed to create organization (may already exist)"
    fi

    # Create repository 
    if ! create_repo; then
        warn "Failed to create repository (may already exist)"
    fi

    # Push source code (optional)
    push_sut_code || true

    log "=========================================="
    log "✅ Gitea initialization complete!"
    log "=========================================="
    log "  URL: ${GITEA_URL}"
    log "  Admin: ${ADMIN_USER}"
    log "  Repository: ${GITEA_URL}/${ORG_NAME}/${REPO_NAME}"
    log "=========================================="
}

# Run main initialization
main "$@"

