﻿/**
 * alien_py_cloud production deploy (canonical Jenkinsfile at repo root)
 *
 * Jenkins: 39.106.135.88 | Target: 39.105.153.68
 * Job Script Path: Jenkinsfile
 *
 */

def DEFAULT_PROD_SSH_TARGET = 'alien_store@39.105.153.68'
def DEFAULT_PROD_SSH_CREDENTIALS_ID = 'e611a045-2fdc-4613-babd-a72d69bf9814'

pipeline {
  agent any

  options {
    buildDiscarder(logRotator(numToKeepStr: '10'))
    timestamps()
  }

  parameters {
    string(name: 'PROD_SSH_TARGET', defaultValue: DEFAULT_PROD_SSH_TARGET,
      description: 'Production host SSH target')
    string(name: 'PROD_SSH_CREDENTIALS_ID', defaultValue: DEFAULT_PROD_SSH_CREDENTIALS_ID,
      description: 'Jenkins SSH Username with private key credential ID')
    string(name: 'GIT_BRANCH', defaultValue: 'produ',
      description: 'alien_py_cloud branch to deploy')
  }

  environment {
    CODE_DIR_REMOTE = '/alien_produ/python/alien_py_cloud'
    ENV_FILE_REMOTE = '/alien_produ/python/alien_py_cloud/.env.produ'
    LOG_ROOT_REMOTE = '/alien_produ/python/alien_py_cloud/logs'

    IMAGE_STORE    = 'alien_store:local'
    IMAGE_GATEWAY  = 'alien_gateway:local'
    IMAGE_CONTRACT = 'alien_contract:local'

    CONTAINER_NAME_STORE    = 'alien_store_produ'
    CONTAINER_NAME_GATEWAY  = 'alien_gateway_produ'
    CONTAINER_NAME_CONTRACT = 'alien_contract_produ'

    PORT_STORE_INTERNAL    = '48001'
    PORT_GATEWAY_INTERNAL  = '43333'
    PORT_CONTRACT_INTERNAL = '8002'
    PORT_GATEWAY_HOST      = '33333'
    PORT_CONTRACT_HOST     = '8002'

    DOCKER_NET = 'alien_net_produ'
  }

  stages {
    stage('Verify SSH') {
      steps {
        script {
          def sshTarget = (params.PROD_SSH_TARGET ?: DEFAULT_PROD_SSH_TARGET).trim()
          def credId = (params.PROD_SSH_CREDENTIALS_ID ?: DEFAULT_PROD_SSH_CREDENTIALS_ID).trim()
          env.SSH_TARGET = sshTarget
          env.SSH_CRED_ID = credId
          sshagent(credentials: [credId]) {
            sh """
              set -e
              ssh -o BatchMode=yes -o StrictHostKeyChecking=accept-new '${sshTarget}' \\
                'test -f ${ENV_FILE_REMOTE} && sudo docker info >/dev/null'
              echo ">>> SSH OK: ${sshTarget}"
            """
          }
        }
      }
    }

    stage('Git Pull on Production') {
      steps {
        sshagent(credentials: [env.SSH_CRED_ID]) {
          sh """
            set -e
            ssh -o BatchMode=yes -o StrictHostKeyChecking=accept-new '${env.SSH_TARGET}' bash -s <<'REMOTE_EOF'
set -e
cd '${CODE_DIR_REMOTE}'
if [ ! -d .git ]; then
  echo "ERROR: ${CODE_DIR_REMOTE} is not a git repo. Clone manually first."
  exit 1
fi
git fetch origin
git checkout '${params.GIT_BRANCH}'
git pull origin '${params.GIT_BRANCH}'
echo ">>> git at \$(git rev-parse --short HEAD) on \$(hostname)"
REMOTE_EOF
          """
        }
      }
    }

    stage('Build Images on Production') {
      steps {
        sshagent(credentials: [env.SSH_CRED_ID]) {
          sh """
            set -e
            ssh -o BatchMode=yes -o StrictHostKeyChecking=accept-new '${env.SSH_TARGET}' bash -s <<'REMOTE_EOF'
set -e
cd '${CODE_DIR_REMOTE}'
sudo docker build -f alien_store/Dockerfile -t ${IMAGE_STORE} .
sudo docker build -f alien_gateway/Dockerfile -t ${IMAGE_GATEWAY} .
sudo docker build -f alien_contract/Dockerfile -t ${IMAGE_CONTRACT} .
echo ">>> images built on \$(hostname)"
sudo docker images | grep -E 'alien_store|alien_gateway|alien_contract' | head -10
REMOTE_EOF
          """
        }
      }
    }

    stage('Deploy on Production') {
      steps {
        sshagent(credentials: [env.SSH_CRED_ID]) {
          sh """
            set -e
            ssh -o BatchMode=yes -o StrictHostKeyChecking=accept-new '${env.SSH_TARGET}' bash -s <<'REMOTE_EOF'
set -e
sudo docker network create ${DOCKER_NET} 2>/dev/null || true
mkdir -p ${LOG_ROOT_REMOTE}/store ${LOG_ROOT_REMOTE}/gateway ${LOG_ROOT_REMOTE}/contract

sudo docker rm -f ${CONTAINER_NAME_STORE} ${CONTAINER_NAME_GATEWAY} ${CONTAINER_NAME_CONTRACT} 2>/dev/null || true

sudo docker run -d --name ${CONTAINER_NAME_STORE} \\
  --network ${DOCKER_NET} \\
  --env-file ${ENV_FILE_REMOTE} \\
  -v ${ENV_FILE_REMOTE}:/app/.env.produ:ro \\
  -v ${LOG_ROOT_REMOTE}/store:/app/common/logs/alien_store \\
  --restart unless-stopped \\
  ${IMAGE_STORE}

sudo docker run -d --name ${CONTAINER_NAME_CONTRACT} \\
  --network ${DOCKER_NET} \\
  -p ${PORT_CONTRACT_HOST}:${PORT_CONTRACT_INTERNAL} \\
  --env-file ${ENV_FILE_REMOTE} \\
  -v ${ENV_FILE_REMOTE}:/app/.env.produ:ro \\
  -v ${LOG_ROOT_REMOTE}/contract:/app/common/logs/alien_contract \\
  --restart unless-stopped \\
  ${IMAGE_CONTRACT}

sudo docker run -d --name ${CONTAINER_NAME_GATEWAY} \\
  --network ${DOCKER_NET} \\
  -p ${PORT_GATEWAY_HOST}:${PORT_GATEWAY_INTERNAL} \\
  --env-file ${ENV_FILE_REMOTE} \\
  -v ${ENV_FILE_REMOTE}:/app/.env.produ:ro \\
  -v ${LOG_ROOT_REMOTE}/gateway:/app/common/logs/alien_gateway \\
  -e STORE_BASE_URL=http://${CONTAINER_NAME_STORE}:${PORT_STORE_INTERNAL} \\
  --restart unless-stopped \\
  ${IMAGE_GATEWAY}

sleep 3
curl -sf http://127.0.0.1:${PORT_GATEWAY_HOST}/health || (echo 'gateway /health failed' && exit 1)
curl -sf http://127.0.0.1:${PORT_CONTRACT_HOST}/health || (echo 'contract /health failed' && exit 1)
sudo docker ps --filter name=${CONTAINER_NAME_STORE} --filter name=${CONTAINER_NAME_GATEWAY} --filter name=${CONTAINER_NAME_CONTRACT}
REMOTE_EOF
          """
        }
      }
    }
  }

  post {
    success {
      echo ">>> alien_py_cloud deployed on ${env.SSH_TARGET}"
    }
    failure {
      echo '>>> failed: check SSH, .env.produ, sudo docker, and remote git path'
    }
    always {
      cleanWs()
    }
  }
}
