#!/bin/bash

# https://access.redhat.com/documentation/en-us/assisted_installer_for_openshift_container_platform/2023/html/assisted_installer_for_openshift_container_platform/index
# https://api.openshift.com/?urls.primaryName=assisted-service%20service

set -ex

PULL_SECRET_FILE="/home/dorzel/.docker/config.json"
SSH_PUB_KEY_FILE="/home/dorzel/.ssh/id_rsa.pub"
PULL_SECRET=$(cat ${PULL_SECRET_FILE} | tr -d '\n' | jq -R .)
SSH_PUB_KEY=$(cat ${SSH_PUB_KEY_FILE})

CONFIG_DIR="/home/dorzel/assisted-workdir/podman-deploy"
IMAGES_DIR="/home/libvirt-openshift-images/dorzel-ocp"
WWW_DIR="/var/www/html/${CLUSTER_NAME}"

API_URL="http://127.0.0.1:8090/api/assisted-install/v2"
CLUSTER_NAME="dorzel-ocp"
CPU_ARCH="ppc64le"
OCP_VERSION="4.15"
BASE_DOMAIN="ocp126.multiarch-ppc64le-018.dev"


provision_podman_services() {
  echo "Starting podman services..."
  podman play kube --configmap ${CONFIG_DIR}/configmap.yml ${CONFIG_DIR}/pod.yml
  echo "Waiting 2 minutes for podman services to come up..."
  sleep 2m
}

provision_libvirt_vms() {
  # set correct libvirt network configuration for single node cluster
  virsh -c qemu+tcp:///system net-define libvirt-netxml-sno.xml
  virsh -c qemu+tcp:///system net-autostart dorzel-ocp
  virsh -c qemu+tcp:///system net-start dorzel-ocp

  # boot the iso (pxe files)
  # hosting the boot files locally over http instead may be required for coreos
#  virt-install --connect qemu+tcp:///system \
#    --name dorzel-ocp.control-0.${BASE_DOMAIN} \
#    --autostart \
#    --vcpus 8 \
#    --memory=32768 \
#    --location "${CONFIG_DIR}/boot-artifacts/,kernel=kernel.img,initrd=initrd.img" \
#    --disk /home/libvirt-openshift-images/dylan-control-0.qcow2,size=120 \
#    --network network=dorzel-ocp,mac=52:54:00:02:17:d2 \
#    --graphics none \
#    --extra-args "coreos.live.rootfs_url=http://10.6.52.81:8888/boot-artifacts/rootfs?arch=x86_64&version=4.15" \
#    --osinfo detect=on,require=off \
#    --noautoconsole \
#    --wait=-1 &

  # boot the iso (iso file)
  virt-install --connect qemu+tcp:///system \
  --name ${CLUSTER_NAME}.control-0.${BASE_DOMAIN} \
  --autostart \
  --vcpus 8 \
  --memory=32768 \
  --cdrom ${IMAGES_DIR}/assisted.iso \
  --disk ${IMAGES_DIR}/${CLUSTER_NAME}-control-0.qcow2,size=120 \
  --network network=dorzel-ocp,mac=52:54:00:02:17:d2 \
  --graphics none \
  --osinfo detect=on,require=off \
  --noautoconsole \
  --wait=-1 &
}

create_cluster() {
  echo "Create cluster for ${CPU_ARCH}..."
  cat > ${CONFIG_DIR}/cluster-create.json << EOF
{
    "base_dns_domain": "${BASE_DOMAIN}",
    "name": "${CLUSTER_NAME}",
    "cpu_architecture": "${CPU_ARCH}",
    "openshift_version": "${OCP_VERSION}",
    "high_availability_mode": "None",
    "pull_secret": ${PULL_SECRET},
    "ssh_public_key": "${SSH_PUB_KEY}",
    "network_type": "OVNKubernetes",
    "cluster_network_cidr": "10.128.0.0/14",
    "cluster_network_host_prefix": 23,
    "service_network_cidr": "172.30.0.0/16"
}
EOF

  curl -s -X POST "${API_URL}/clusters" \
      -H "Content-Type: application/json" \
      -d @${CONFIG_DIR}/cluster-create.json | jq . > ${CONFIG_DIR}/create-output.json

  export NEW_CLUSTER_ID=$(cat ${CONFIG_DIR}/create-output.json | jq '.id' | awk -F'"' '{print $2}')
  if [[ -z $NEW_CLUSTER_ID ]]; then
    echo "Failed to create the cluster ${CLUSTER_NAME}"
    cat ${CONFIG_DIR}/create-output.json
    exit 1
  fi
}

register_infra() {
  echo "Register the cluster: ${NEW_CLUSTER_ID}"
  STATIC_NETWORK_CONFIG=$(cat static-network-config.json)
  cat > ${CONFIG_DIR}/cluster-infra.json << EOF
{
    "cluster_id": "${NEW_CLUSTER_ID}",
    "name": "${CLUSTER_NAME}-infra-env",
    "cpu_architecture": "${CPU_ARCH}",
    "openshift_version": "${OCP_VERSION}",
    "image_type": "full-iso",
    "pull_secret": ${PULL_SECRET},
    "ssh_authorized_key": "${SSH_PUB_KEY}",
    "static_network_config": ${STATIC_NETWORK_CONFIG}
}
EOF

  curl -s -X POST "${API_URL}/infra-envs" \
      -H "Content-Type: application/json" \
      -d @${CONFIG_DIR}/cluster-infra.json | jq . > ${CONFIG_DIR}/infra-output.json

  export NEW_INFRAENVS_ID=$(cat ${CONFIG_DIR}/infra-output.json | jq '.id' | awk -F'"' '{print $2}')
  export ISO_URL=$(cat ${CONFIG_DIR}/infra-output.json | jq '.download_url' | awk -F'"' '{print $2}')
  if [[ -z $ISO_URL ]]; then
    echo "Could not register cluster"
    cat ${CONFIG_DIR}/infra-output.json
    exit 1
  fi
}

download_iso() {
  echo "Waiting 6 minutes for iso to be created..."
  sleep 6m
  echo "Downloading ISO at ${ISO_URL} ..."
  wget --quiet -O ${IMAGES_DIR}/assisted.iso ${ISO_URL}

  if [[ -f "${IMAGES_DIR}/assisted.iso" ]]; then
    echo "successfully downloaded iso."
    chmod a+x ${IMAGES_DIR}/assisted.iso
#    echo "Extracting pxe files from ISO..."
#    rm -rf ${IMAGES_DIR}/pxe
#    mkdir ${IMAGES_DIR}/pxe
#    coreos-installer iso ignition show ${IMAGES_DIR}/assisted.iso > ${IMAGES_DIR}/pxe/assisted.ign
#    coreos-installer iso extract pxe -o ${IMAGES_DIR}/pxe ${IMAGES_DIR}/assisted.iso
#
#    echo "install pxe file to tftp/http"
#    cp ${IMAGES_DIR}/pxe/assisted-initrd.img ${IMAGES_DIR}/initramfs.img
#    cp ${IMAGES_DIR}/pxe/assisted-vmlinuz ${IMAGES_DIR}/kernel
#    chmod +x ${IMAGES_DIR}/*
#    cp ${IMAGES_DIR}/pxe/assisted-rootfs.img ${WWW_DIR}/rootfs.img
#    chmod +x ${WWW_DIR}/rootfs.img
#    cp ${IMAGES_DIR}/pxe/assisted.ign ${WWW_DIR}/bootstrap.ign
  else
    echo "Failed to download ISO at ${ISO_URL}"
    exit 1
  fi
}

get_cluster_status() {
  echo "Getting cluster status..."
  curl -s -X GET "${API_URL}/clusters/${NEW_CLUSTER_ID}" | jq . > ${CONFIG_DIR}/cluster-status-output.json
}

start_install() {
  echo "Start install"
  curl -s -X POST "${API_URL}/clusters/${NEW_CLUSTER_ID}/actions/install" \
      -H "Content-Type: application/json" | jq . > ${CONFIG_DIR}/cluster-start-install-output.json
}

download_kubeconfig() {
  echo "Download kubeconfig..."
  mkdir -p ${CONFIG_DIR}/auth
  curl -s -X GET "${API_URL}/clusters/${NEW_CLUSTER_ID}/downloads/credentials?file_name=kubeconfig" > ${CONFIG_DIR}/auth/kubeconfig
  curl -s -X GET "${API_URL}/clusters/${NEW_CLUSTER_ID}/downloads/credentials?file_name=kubeadmin-password" > ${CONFIG_DIR}/auth/kubeadmin-password
#   mkdir -p ~/.kube
#   cp ${CONFIG_DIR}/auth/kubeconfig ~/.kube/config
}

wait_to_install() {
  echo "Waiting to install..."
  for i in {1..15}; do
    get_cluster_status
    status=$(cat ${CONFIG_DIR}/cluster-status-output.json | jq '.status' | awk -F'"' '{print $2}')
    echo "Current cluster_status: ${status}"
    if [[ ${status} == "ready" ]]; then
      sleep 30
      start_install
    elif [[ ${status} == "installed" || ${status} == "installing" ]]; then
      download_kubeconfig
      break
    fi
    sleep 60
  done
}

wait_install_complete() {
  echo "Waiting for the installation to complete..."
  pre_status=""
  for i in {1..15}; do
    get_cluster_status
    status=$(cat ${CONFIG_DIR}/cluster-status-output.json | jq '.status' | awk -F'"' '{print $2}')
    if [[ ${pre_status} != ${status} ]]; then
      echo "Current installation status: ${status} : ${i}"
      pre_status=${status}
    fi
    if [[ ${status} == "installed" ]]; then
      echo "OCP installation complete."
      break
    fi
    sleep 60
  done
}

ai_prepare_cluster() {
  provision_podman_services
  create_cluster
  register_infra
  download_iso
  provision_libvirt_vms
}

ai_wait_complete() {
  export NEW_CLUSTER_ID=$(cat ${CONFIG_DIR}/create-output.json | jq '.id' | awk -F'"' '{print $2}')
  wait_to_install
  wait_install_complete
}

main() {
  ai_prepare_cluster
  echo "Waiting for 2 minutes for VMs to provision..."
  sleep 2m
  ai_wait_complete
}

main
