#!/bin/sh
#
# Copyright (C) 2021  Kostarev Alexey <kaf@altlinux.org>
#
# The utility for Zincatti utility for deploying a new repository and rebooting the system 
#
# SPDX-License-Identifier: GPL-3.0-or-later

exec 2>>/var/log/alt-ostree/log
set -x
echo "
----------------------" >&2

export _OSTREE_SYSROOT_RUNSTATE_STAGED_LOCKED=/run/ostree/staged-deployment-locked

getBootInfo () {
  ostree admin status |
  (
  set -f
  while read line1
  do
    ifs=$IFS
    set -- $line1
    if [ "$1" = '*' ]
    then
      booted=true
      shift
    else
      booted=false
    fi
    osname=$1
    checksum=${2:0:64}
    id=${2:65}
    read line2
    set -- $line2
    version=$2
    read line3
    set -- $line3
    origin=$3

    if [ "$booted" = true ]
    then
      echo osname=\"$osname\" checksum=\"$checksum\" id=$id version=\"$version\" origin=\"$origin\" 
      return
    fi
  done
  )
}

# deploy FUNCTIONS
deploy() {
  revision=$1
  echo "deploy:: revision=$revision ID=" `id`  >&2
  mkdir -p $_OSTREE_SYSROOT_RUNSTATE_STAGED_LOCKED
  eval `getBootInfo` 
  sudo ostree pull altcos $revision
  sudo ostree refs --delete $origin 
  sudo ostree refs --create=$origin $revision
  sudo ostree admin deploy $origin  
}

# finalize_deployment FUNCTIONS

check_sd_inhibitor_locks() {
  systemd-inhibit --list
}


finalize_deployment() {
  release_checksum=$1
  echo "finalize_deployment: release_checksum=$release_checksum ID=" `id`  >&2

  if [ ! -d $_OSTREE_SYSROOT_RUNSTATE_STAGED_LOCKED ]
  then
    echo "Staged deployment already unlocked"
    exit 16
  fi
  if ! error=`rmdir $_OSTREE_SYSROOT_RUNSTATE_STAGED_LOCKED 2>&1`
  then
    echo "unlink $_OSTREE_SYSROOT_RUNSTATE_STAGED_LOCKED error: $error"
    exit 17
  fi
  sudo /sbin/reboot 
}

# status FUNCTIONS

status() {
  echo "status::" >&2
#   cat ~kaf/tmp/adminstatus |
  ostree admin  status |
  (
  set -f
  n=0
  while read line1
  do
    ifs=$IFS
    set -- $line1
    if [ "$1" = '*' ]
    then
      booted=true
      shift
    else
      booted=false
    fi
    osname=$1
    checksum=${2:0:64}
    id=${2:65}
    read line2
    set -- $line2
    version=$2
    read line3
    set -- $line3
    origin=$3
    IFS=/
    set -- $origin
    IFS=$ifs
    basearch=$2
    stream=$3
    deployments=`echo $deployments '{"base-commit-meta":{
      "mkimage.basearch" : "'$basearch'",
      "acos.stream" : "'$stream'"
      },
    "osname" : "'$osname'",
    "checksum" : "'$checksum'",
    "origin" : "'$origin'",
    "version" : "'$version'",
    "booted" : '$booted'
    },'`
    let n=$n+1
  done
  len=`echo ${#deployments}`
  let len=len-1
  deployments='{"deployments":['${deployments:0:$len}']}'
  echo $deployments
  )
}

format() {
  echo "Format:" >&2
  if [ $# -eq 0 -o "$1" = 'deploy' ]
  then
    echo "$0 deploy --lock-finalization revision=<revision> [--disallow-downgrade]" >&2
    echo "$0 deploy --register-driver=Zincati" >&2
  fi
  if [ $# -eq 0 -o "$1" = 'finalize-deployment' ] >&2
  then
    echo "$0 finalize-deployment <release_checksum>" >&2
  fi
  if [ $# -eq 0 -o "$1" = 'status' ]
  then
    echo "$0 status --booted --json"  >&2
    echo "$0 status --json"  >&2
  fi
}


# MAIN
echo  ARGS=$* >&2
if [ $# -eq 0 ] 
then 
  format 
  exit 1; 
fi
# MAIN
# deploy --lock-finalization revision=da97eb802fc30485fb8d5fb238fceb5f19c7f780885e06ae34d5e749741493e9 --disallow-downgrade
cmd=$1
shift
case $cmd in
  deploy)
    for flag
    do
      if [ "${flag:0:9}" = 'revision=' ]; then revision=${flag:9}; continue; fi
      case $flag in
        '--lock-finalization') lock_finalization=1; ;;
        '--disallow-downgrade') disallow_downgrade=1; ;;
        '--register-driver=Zincati') register_driver=1; exit 0; ;;
      esac
    done
    deploy $revision
    break;
    ;;
  finalize-deployment)
    if [ $# != 1 ]
    then
      format finalize-deployment
      exit 4;
    fi
    release_checksum=$1
    finalize_deployment $release_checksum
    break;
    ;;
  status)
    export booted
    for flag
    do
      case $flag in
        '--booted') booted=1;;
        '--json') json=1;;
        *) format status;;
      esac
    done
    if [ -z "json" ]; then format status; exit 3; fi
    status
    break;
    ;;
  *)
    format 
    exit 2;
esac    
