#!/bin/bash
set -e

# Retry helm s3 push with backoff to handle S3 PreconditionFailed 412 race conditions
helm_s3_push_with_retry() {
    local chart_file="$1"
    local repo_name="$2"
    local max_retries=5
    local attempt=1
    local wait_time=5
    while [ $attempt -le $max_retries ]; do
        if helm s3 push "${chart_file}" "${repo_name}" --force 2>&1; then
            return 0
        fi
        echo "helm s3 push failed (attempt ${attempt}/${max_retries}), retrying in ${wait_time}s..."
        sleep $wait_time
        wait_time=$((wait_time * 2))
        attempt=$((attempt + 1))
    done
    echo "ERROR: helm s3 push failed after ${max_retries} attempts"
    return 1
}

# Retry git push with rebase to handle concurrent pipeline race conditions
git_push_with_retry() {
    local branch="${1:-master}"
    local max_retries=5
    local attempt=1
    while [ $attempt -le $max_retries ]; do
        if git push origin "$branch" 2>&1; then
            return 0
        fi
        echo "Push failed (attempt ${attempt}/${max_retries}), rebasing and retrying..."
        git pull --rebase origin "$branch"
        attempt=$((attempt + 1))
    done
    echo "ERROR: Failed to push after ${max_retries} attempts"
    return 1
}
echo "=== Starting deployment of TBI RLV Vacations Frontend ==="

# Configuration
NAMESPACE="rlv"
ENVIRONMENT="${DEPLOY_ENV:-dev}"
AWS_REGION="${AWS_REGION:-ca-central-1}"
TBI_ENVIRONMENTS_BRANCH="${TBI_ENVIRONMENTS_BRANCH:-master}"
HELM_REPO_URL="${HELM_REPO_URL:-https://tbi-charts.s3.amazonaws.com}"
HELM_S3_BUCKET="${HELM_S3_BUCKET:-tbi-charts}"

# Validate required environment variables
if [ -z "${CLUSTER_NAME}" ]; then
    echo "ERROR: CLUSTER_NAME environment variable is not set!"
    echo "This should be set in CircleCI context (e.g., 'dev', 'rlv-prod', etc.)"
    exit 1
fi

if [ -z "${AWS_ACCOUNT_ID}" ]; then
    echo "ERROR: AWS_ACCOUNT_ID environment variable is not set!"
    echo "This is required to construct ECR image URLs"
    exit 1
fi

# GitHub authentication - uses GITHUB_TOKEN for HTTPS access
if [ -z "${GITHUB_TOKEN}" ]; then
    echo "ERROR: GITHUB_TOKEN environment variable is not set!"
    echo "This token is required to clone and push to tbi-environments repository"
    exit 1
fi
# Clean URL - no inline token (credential helper supplies it at request time)
TBI_ENVIRONMENTS_REPO="https://github.com/redlabelvacations/tbi-environments.git"

# Read image tag from workspace (created by build job)
if [ -f "IMAGE_TAG" ]; then
    CHART_VERSION=$(cat IMAGE_TAG | tr -d '[:space:]')
    echo "Using image tag from build job: ${CHART_VERSION}"
else
    echo "WARNING: IMAGE_TAG file not found, calculating from VERSION file"
    if [ ! -f "VERSION" ]; then
        echo "ERROR: VERSION file not found!"
        exit 1
    fi
    BASE_VERSION=$(cat VERSION | tr -d '[:space:]')
    CHART_VERSION="${BASE_VERSION}-${CIRCLE_BRANCH}-${CIRCLE_BUILD_NUM}"
fi

echo "Chart Version: ${CHART_VERSION}"
echo "Environment: ${ENVIRONMENT}"
echo "Namespace: ${NAMESPACE}"
echo "Cluster: ${CLUSTER_NAME}"

# List of services to deploy
SERVICES=(
    "tbi-rlv-tours-connector-service"
)

# Function to package Helm chart
package_helm_chart() {
    local service=$1
    echo ""
    echo "=== Packaging Helm chart for ${service} ==="

    local chart_path="tbi-devops-environments/dev/tbi-rlv-tours-connector-service/charts/${service}"

    if [ ! -d "${chart_path}" ]; then
        echo "ERROR: Chart directory not found: ${chart_path}"
        return 1
    fi

    # Update Chart.yaml with new version
    echo "Updating chart version to ${CHART_VERSION}..."
    sed -i.bak "s|version:.*|version: ${CHART_VERSION}|g" ${chart_path}/Chart.yaml
    sed -i.bak "s|appVersion:.*|appVersion: \"${CHART_VERSION}\"|g" ${chart_path}/Chart.yaml
    rm -f ${chart_path}/Chart.yaml.bak

    # Package the chart
    echo "Packaging chart..."
    mkdir -p /tmp/helm-charts
    helm package ${chart_path} -d /tmp/helm-charts

    echo "✓ ${service} chart packaged"
}

# Function to push chart to S3 Helm repository using helm-s3 plugin
push_chart_to_s3_repo() {
    local service=$1
    local chart_file="/tmp/helm-charts/${service}-${CHART_VERSION}.tgz"

    echo ""
    echo "=== Pushing ${service} chart to S3 Helm repository ==="

    if [ ! -f "${chart_file}" ]; then
        echo "ERROR: Chart file not found: ${chart_file}"
        return 1
    fi

    # Use helm-s3 plugin to push chart (automatically updates index.yaml)
    helm_s3_push_with_retry ${chart_file} tbi-charts

    echo "✓ ${service} chart pushed to S3 repository"
}

# Function to clone tbi-environments repository
clone_tbi_environments() {
    echo "Cloning tbi-environments repository..."
    git -c credential.helper= \
        -c credential.helper='!f() { echo "username=x-access-token"; echo "password=${GITHUB_TOKEN}"; }; f' \
        clone "${TBI_ENVIRONMENTS_REPO}" -b "${TBI_ENVIRONMENTS_BRANCH}"
    # Persist the helper so the later git push also authenticates
    git -C tbi-environments config credential.helper '!f() { echo "username=x-access-token"; echo "password=${GITHUB_TOKEN}"; }; f'
}

# Function to update values file with new image URL
update_values_file() {
    local service=$1
    local ecr_registry="${AWS_ACCOUNT_ID}.dkr.ecr.${AWS_REGION}.amazonaws.com"
    local image_url="${ecr_registry}/${service}:${CHART_VERSION}"

    echo ""
    echo "=== Updating values file for ${service} ==="
    echo "New image URL: ${image_url}"

    local values_file="tbi-environments/${ENVIRONMENT}/values/${service}.yaml"

    if [ ! -f "${values_file}" ]; then
        echo "ERROR: Values file not found: ${values_file}"
        return 1
    fi

    # Update image repository and tag in values file
    sed -i.bak "s|image:.*|image: ${image_url}|g" ${values_file}
    rm -f ${values_file}.bak

    echo "✓ Values file updated"
}

# Function to commit and push values file updates
push_values_update() {
    echo ""
    echo "=== Committing and pushing values file updates ==="

    cd tbi-environments

    # Configure git
    git config user.name "CircleCI"
    git config user.email "circleci@redlabelvacations.com"

    # Add and commit changes
    git add .
    git commit -m "Update ${SERVICES[*]} image to ${CHART_VERSION} for ${ENVIRONMENT} environment

Automated deployment from CircleCI
Branch: ${CIRCLE_BRANCH}
Build: ${CIRCLE_BUILD_NUM}" || echo "No changes to commit"

    # Push changes
    git_push_with_retry "${TBI_ENVIRONMENTS_BRANCH}"

    cd ..
    echo "✓ Values files updated in tbi-environments repository"
}

# Function to deploy service using helm secrets
deploy_service() {
    local service=$1

    echo ""
    echo "=== Deploying ${service} using helm secrets ==="

    cd tbi-environments

    # NOTE: Image is read from values/${service}.yaml, NOT from --set parameter
    # This ensures ArgoCD-compatible configuration and uses Git-tracked values
    echo "Running: helm secrets upgrade --install --namespace ${NAMESPACE} ${service} --set cluster=${CLUSTER_NAME} --version ${CHART_VERSION}"
    helm secrets upgrade --install \
        --namespace ${NAMESPACE} ${service} \
        tbi-charts/${service} \
        --set cluster="${CLUSTER_NAME}" \
        --version ${CHART_VERSION} \
        --reset-values \
        -f ./${ENVIRONMENT}/common.yaml \
        -f ./${ENVIRONMENT}/secrets.common.yaml \
        -f ./${ENVIRONMENT}/values/${service}.yaml \
        -f ./${ENVIRONMENT}/secrets/secrets.${service}.yaml

    # Verify deployment
    echo "Verifying deployment..."
    kubectl rollout status deployment/${service} -n ${NAMESPACE} --timeout=5m

    echo "✓ ${service} deployed successfully"
}

# Main deployment flow
echo ""
echo "=== Step 1: Package Helm charts ==="
for service in "${SERVICES[@]}"; do
    package_helm_chart "${service}"
done

echo ""
echo "=== Step 2: Initialize Helm S3 repository ==="
helm repo add tbi-charts s3://${HELM_S3_BUCKET}/

echo ""
echo "=== Step 3: Push charts to S3 repository ==="
for service in "${SERVICES[@]}"; do
    push_chart_to_s3_repo "${service}"
done

echo ""
echo "=== Step 4: Clone tbi-environments repository ==="
clone_tbi_environments

echo ""
echo "=== Step 5: Update values files with image URLs ==="
for service in "${SERVICES[@]}"; do
    update_values_file "${service}"
done

echo ""
echo "=== Step 6: Commit and push values file updates ==="
push_values_update

echo ""
echo "=== Step 7: Deploy services ==="
for service in "${SERVICES[@]}"; do
    deploy_service "${service}"
done

echo ""
echo "🎉 All services deployed successfully!"
echo ""
echo "=== Deployment Summary ==="
for service in "${SERVICES[@]}"; do
    echo "✅ ${service}: ${CHART_VERSION}"
done
