pipeline {
    agent any

    parameters {
        string(
                name: 'BRANCH',
                defaultValue: 'dev',
                description: 'Ветка для деплоя'
        )
        string(
                name: 'PORT',
                defaultValue: '3001',
                description: 'Порт для запуска экземпляра'
        )
        string(
                name: 'PORT_DB',
                defaultValue: '',
                description: 'Порт для запуска БД'
        )
        string(
                name: 'SERVER',
                defaultValue: '92.242.61.23',
                description: 'Сервер для деплоя'
        )
        string(
                name: 'NETWORK',
                defaultValue: 'app-network-dev',
                description: 'Имя сети (будет создана если не существует)'
        )
        choice(
                name: 'SPRING_PROFILE',
                choices: ['dev', 'prod'],
                description: 'Профиль Spring для запуска'
        )
    }

    stages {
        stage('Git pull') {
            steps {
                cleanWs()
                script {
                    checkout([
                            $class: 'GitSCM',
                            branches: [[name: params.BRANCH]],
                            userRemoteConfigs: [[
                                                        url: 'https://code.3err0.ru/backdev/no-copy.git',
                                                        credentialsId: 'nx-jen'
                                                ]]
                    ])
                }
            }
        }

        stage('Copy to server') {
            steps {
                script {
                    withCredentials([
                            usernamePassword(
                                    credentialsId: 'server-root-password',
                                    usernameVariable: 'SSH_USER',
                                    passwordVariable: 'SSH_PASS'
                            )
                    ]) {
                        sh """
                    sshpass -p '${SSH_PASS}' ssh -o StrictHostKeyChecking=no ${SSH_USER}@${params.SERVER} "
                        rm -rf /opt/deployments/${params.BRANCH}-${params.PORT}/*
                        mkdir -p /opt/deployments/${params.BRANCH}-${params.PORT}
                    "
                    
                    sshpass -p '${SSH_PASS}' scp -r ./* ${SSH_USER}@${params.SERVER}:/opt/deployments/${params.BRANCH}-${params.PORT}/
                """
                    }
                }
            }
        }

        stage('Deploy with docker-compose') {
            steps {
                script {
                    def buildTime = sh(script: "TZ='Asia/Novosibirsk' date '+%d-%m-%Y %H:%M:%S'", returnStdout: true).trim()
                    def springProfile = params.SPRING_PROFILE
                    withCredentials([
                            usernamePassword(
                                    credentialsId: 'server-root-password',
                                    usernameVariable: 'SSH_USER',
                                    passwordVariable: 'SSH_PASS'
                            ),
                            string(credentialsId: 'DB_USER', variable: 'DB_USER'),
                            string(credentialsId: 'DB_PASSWORD', variable: 'DB_PASSWORD'),
                            string(credentialsId: 'MONGO_USER', variable: 'MONGO_USER'),
                            string(credentialsId: 'MONGO_PASSWORD', variable: 'MONGO_PASSWORD')
                    ]) {
                        sh """
                echo "Testing SSH connection..."
                if sshpass -p '${SSH_PASS}' ssh -o StrictHostKeyChecking=no ${SSH_USER}@${params.SERVER} 'echo "SSH connection successful"'; then
                    echo "SSH connection OK"
                else
                    echo "SSH connection failed"
                    exit 1
                fi

                sshpass -p '${SSH_PASS}' ssh -o StrictHostKeyChecking=no ${SSH_USER}@${params.SERVER} "
                    mkdir -p /opt/deployments/${params.BRANCH}-${params.PORT}
                    cd /opt/deployments/${params.BRANCH}-${params.PORT}

                    echo '1. Проверяем/создаем сеть ${params.NETWORK}...'
                    if ! docker network ls --format '{{.Name}}' | grep -q '^${params.NETWORK}\$'; then
                        docker network create ${params.NETWORK}
                        echo 'Сеть ${params.NETWORK} создана'
                    else
                        echo 'Сеть ${params.NETWORK} уже существует'
                    fi

                    echo '2. Останавливаем старые контейнеры порта ${params.PORT}...'
                    docker stop app-backend-${params.PORT} 2>/dev/null || echo 'Контейнер не найден'
                    docker rm app-backend-${params.PORT} 2>/dev/null || echo 'Контейнер не найден'
                    docker stop postgres-${params.PORT} 2>/dev/null || echo 'Контейнер БД не найден'
                    docker rm postgres-${params.PORT} 2>/dev/null || echo 'Контейнер БД не найден'
                    docker stop file-storage-${params.PORT} 2>/dev/null || echo 'Контейнер storage не найден'
                    docker rm file-storage-${params.PORT} 2>/dev/null || echo 'Контейнер storage не найден'
                    docker stop mongodb-${params.PORT} 2>/dev/null || echo 'Контейнер MongoDB не найден'
                    docker rm mongodb-${params.PORT} 2>/dev/null || echo 'Контейнер MongoDB не найден'

                    echo '3. Запускаем БД...'
                    docker run -d \\
                      --name postgres-${params.PORT} \\
                      --network ${params.NETWORK} \\
                      --network-alias no_copy_${params.PORT} \\
                      --network-alias database-${params.PORT} \\
                      --network-alias db-${params.PORT} \\
                      -p ${params.PORT}0:5432 \\
                      -e POSTGRES_DB=no_copy${params.PORT_DB} \\
                      -e POSTGRES_USER=${DB_USER} \\
                      -e POSTGRES_PASSWORD=${DB_PASSWORD} \\
                      -v pgdata_${params.PORT}:/var/lib/postgresql/data \\
                      -e BUILD_TIME_BACK='${buildTime}' \\
                      postgres:17.7

                    echo '4. Запускаем MongoDB...'
                    docker run -d \\
                      --name mongodb-${params.PORT} \\
                      --network ${params.NETWORK} \\
                      --network-alias mongodb-${params.PORT} \\
                      -p ${params.PORT}1:27017 \\
                      -e MONGO_INITDB_ROOT_USERNAME=${MONGO_USER} \\
                      -e MONGO_INITDB_ROOT_PASSWORD=${MONGO_PASSWORD} \\
                      -v mongodb_data_${params.PORT}:/data/db \\
                      mongo:7.0

                    echo '5. Запускаем storage...'
                    docker run -d \\
                      --name file-storage-${params.PORT} \\
                      --network ${params.NETWORK} \\
                      -v uploads_data_${params.PORT}:/storage:rw \\
                      alpine:latest tail -f /dev/null

                    echo '6. Ждем БД...'
                    sleep 15

                    echo '7. Собираем приложение...'
                    docker build --no-cache -t app-backend-${params.PORT}:latest .

                    echo '8. Запускаем приложение...'
                    docker run -d \\
                      --name app-backend-${params.PORT} \\
                      --network ${params.NETWORK} \\
                      --network-alias app \\
                      --network-alias app-${params.PORT} \\
                      -p ${params.PORT}:8080 \\
                      -v uploads_data_${params.PORT}:/data/uploads:rw \\
                      -e POSTGRES_DB=no_copy${params.PORT_DB} \\
                      -e POSTGRES_USER=${DB_USER} \\
                      -e POSTGRES_PASSWORD=${DB_PASSWORD} \\
                      -e POSTGRES_PORT=5432 \\
                      -e POSTGRES_HOST=no_copy_${params.PORT} \\
                      -e FILE_STORAGE_PATH=/data/uploads \\
                      -e SPRING_PROFILES_ACTIVE=${springProfile} \\
                      -e MONGO_URI=mongodb://${MONGO_USER}:${MONGO_PASSWORD}@mongodb-${params.PORT}:27017 \\
                      -e MONGO_DATABASE=no_copy \\
                      app-backend-${params.PORT}:latest

                    echo '9. Проверка...'
                    sleep 10
                    
                    if curl -s -f http://localhost:${params.PORT}/health > /dev/null 2>&1; then
                        echo 'Приложение работает на порту ${params.PORT}'
                    else
                        echo 'Проверка health не удалась'
                        docker logs app-backend-${params.PORT} --tail=20
                    fi
                "
                """
                    }
                }
            }
        }

        stage('Verify network') {
            steps {
                script {
                    withCredentials([
                            usernamePassword(
                                    credentialsId: 'server-root-password',
                                    usernameVariable: 'SSH_USER',
                                    passwordVariable: 'SSH_PASS'
                            )
                    ]) {
                        sh """
                        sshpass -p '${SSH_PASS}' ssh -o StrictHostKeyChecking=no ${SSH_USER}@${params.SERVER} "
                            echo 'Проверяем подключение к сети ${params.NETWORK}'
                            docker network inspect ${params.NETWORK} --format='{{.Name}}: {{range .Containers}}{{.Name}} {{end}}'
                            
                            echo 'Проверяем алиас app для контейнера app-backend-${params.PORT}'
                            docker inspect app-backend-${params.PORT} | grep -A 5 'Aliases'
                        "
                        """
                    }
                }
            }
        }
    }

    post {
        success {
            script {
                def appUrl = params.SPRING_PROFILE == 'prod' ? 'https://workspace.not-copy.com' : 'https://dev-workspace.not-copy.com'
                echo "Deployment successful"
                echo "Application URL: ${appUrl}"
            }
        }
        failure {
            echo "Deployment failed for branch ${params.BRANCH} on port ${params.PORT}"
        }
        always {
            echo "Deployment process finished"
        }
    }
}