/**
 * alien_py_cloud production deploy (repo root Jenkinsfile)
 * Jenkins: 39.106.135.88 | Target: 39.105.153.68 | 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    = 'py_esign_produ'
    CONTAINER_NAME_GATEWAY  = 'py_gateway_produ'
    CONTAINER_NAME_CONTRACT = 'py_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
# legacy / previous container names (same host ports)
sudo docker rm -f esign alien_gateway_py alien_contract_py \\
  alien_store_produ alien_gateway_produ alien_contract_produ 2>/dev/null || true

wait_http() {
  url="\$1"
  label="\$2"
  cname="\$3"
  for i in \$(seq 1 30); do
    if curl -sf "\$url" >/dev/null 2>&1; then
      echo ">>> \$label OK: \$url"
      return 0
    fi
    sleep 2
  done
  echo ">>> \$label FAILED: \$url"
  if [ -n "\$cname" ]; then
    echo ">>> docker ps -a:"
    sudo docker ps -a --filter name="\$cname" || true
    echo ">>> docker logs --tail 100 \$cname:"
    sudo docker logs --tail 100 "\$cname" 2>&1 || true
  fi
  return 1
}

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 \\
  -e SNOWFLAKE_WORKER_IP=127.0.0.1 \\
  --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 \\
  -e SNOWFLAKE_WORKER_IP=127.0.0.1 \\
  --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} \\
  -e SNOWFLAKE_WORKER_IP=127.0.0.1 \\
  --restart unless-stopped \\
  ${IMAGE_GATEWAY}

wait_http "http://127.0.0.1:${PORT_CONTRACT_HOST}/health" "contract" "${CONTAINER_NAME_CONTRACT}"
wait_http "http://127.0.0.1:${PORT_GATEWAY_HOST}/health" "gateway" "${CONTAINER_NAME_GATEWAY}"
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()
    }
  }
}
