// Jenkinsfile for Rocky Man
//
// This repo holds only the deploy pipeline. The application source is pulled
// from the upstream repository at build time (see SOURCE_REPO / SOURCE_REF),
// so the code is not duplicated here.
pipeline {
    agent {
        kubernetes {
            yaml """
apiVersion: v1
kind: Pod
metadata:
  labels:
    jenkins: agent
spec:
  containers:
  - name: docker
    image: docker:24-dind
    securityContext:
      privileged: true
    volumeMounts:
    - name: docker-sock
      mountPath: /var/run
    command:
    - dockerd-entrypoint.sh
  - name: docker-cli
    image: docker:24-cli
    command:
    - cat
    tty: true
    volumeMounts:
    - name: docker-sock
      mountPath: /var/run
  volumes:
  - name: docker-sock
    emptyDir: {}
"""
        }
    }

    parameters {
        string(
            name: 'SOURCE_REPO',
            defaultValue: 'https://git.resf.org/documentation/rocky-man.git',
            description: 'Upstream application repository to build'
        )
        string(
            name: 'SOURCE_REF',
            defaultValue: 'main',
            description: 'Branch or tag of the application to build'
        )
        string(
            name: 'VERSIONS',
            defaultValue: '8.10 9.8 10.2',
            description: 'Rocky Linux versions to build (space-separated)'
        )
        string(
            name: 'REPO_TYPES',
            defaultValue: 'BaseOS AppStream HighAvailability',
            description: 'Rocky Linux repos to build against (space-separated)'
        )
        string(
            name: 'R2_BUCKET_NAME',
            defaultValue: 'rockyman',
            description: 'R2 bucket name for uploads'
        )
        string(
            name: 'EXISTING_VERSIONS',
            defaultValue: '',
            description: 'Existing versions already built (space-separated)'
        )
        string(
            name: 'PARALLEL_DOWNLOADS',
            defaultValue: '5',
            description: 'Number of parallel downloads'
        )
        string(
            name: 'PARALLEL_CONVERSIONS',
            defaultValue: '10',
            description: 'Number of parallel conversions'
        )
    }

    options {
        buildDiscarder(logRotator(numToKeepStr: '10'))
        timeout(time: 2, unit: 'HOURS')
    }

    stages {
        stage('Checkout Source') {
            steps {
                dir('rocky-man') {
                    git url: "${params.SOURCE_REPO}", branch: "${params.SOURCE_REF}"
                }
            }
        }

        stage('Build Docker Image') {
            steps {
                container('docker-cli') {
                    sh '''
until docker info > /dev/null 2>&1; do
  echo "Waiting for Docker daemon..."
  sleep 2
done
docker build -t rocky-man:${BUILD_NUMBER} rocky-man
docker tag rocky-man:${BUILD_NUMBER} rocky-man:latest
                    '''
                }
            }
        }

        stage('Build Man Pages') {
            steps {
                container('docker-cli') {
                    sh '''
mkdir -p ./html ./tmp

docker run --rm \
  -v "$(pwd)/html:/data/html" \
  -v "$(pwd)/tmp:/data/tmp" \
  rocky-man:${BUILD_NUMBER} \
      --versions ${VERSIONS} \
      --repo-types ${REPO_TYPES} \
      --parallel-downloads ${PARALLEL_DOWNLOADS} \
      --parallel-conversions ${PARALLEL_CONVERSIONS} \
      --existing-versions ${EXISTING_VERSIONS}
                    '''
                }
            }
        }

        stage('Upload to R2') {
            when {
                expression { return params.R2_BUCKET_NAME != "" }
            }
            steps {
                container('docker-cli') {
                    withCredentials([
                        string(credentialsId: 'r2-account-id', variable: 'R2_ACCOUNT_ID'),
                        string(credentialsId: 'r2-access-key-id', variable: 'AWS_ACCESS_KEY_ID'),
                        string(credentialsId: 'r2-secret-access-key', variable: 'AWS_SECRET_ACCESS_KEY')
                    ]) {
                        // When EXISTING_VERSIONS is set this is a partial rebuild,
                        // so omit --delete to preserve versions already in the bucket.
                        sh '''
if [ -n "${EXISTING_VERSIONS}" ]; then
  DELETE_FLAG=""
  echo "Partial rebuild (EXISTING_VERSIONS set) -- preserving existing objects."
else
  DELETE_FLAG="--delete"
  echo "Full rebuild -- bucket will be synced with --delete."
fi

docker run --rm \
  -v "$(pwd)/html:/workspace/html" \
  -e AWS_ACCESS_KEY_ID \
  -e AWS_SECRET_ACCESS_KEY \
  peakcom/s5cmd:latest \
  --endpoint-url "https://${R2_ACCOUNT_ID}.r2.cloudflarestorage.com" \
  sync ${DELETE_FLAG} /workspace/html/ "s3://${R2_BUCKET_NAME}/"
                        '''
                    }
                }
            }
        }
    }

    post {
        success {
            echo 'Build completed and uploaded to R2!'
        }
        failure {
            echo 'Build failed!'
        }
        cleanup {
            container('docker-cli') {
                sh '''
docker rmi rocky-man:${BUILD_NUMBER} || true
docker rmi rocky-man:latest || true
                '''
            }
        }
    }
}
