#!/bin/bash

echo "ms pre-start:[$@] start" >&2

USER="ms"
GROUP="unifi-streaming"
EXTERNAL_MINIMUM_SPACE=54683238
if [ -z ${MS_TMPFS_DIR} ]; then
  echo "MS_TMPFS_DIR is not set - using default /var/opt/ms/tmp"
  MS_TMPFS_DIR="/var/opt/ms/tmp"
fi

if [ -z ${MS_INTERNAL_DIR} ]; then
  echo "MS_INTERNAL_DIR is not set - using default /data/ms"
  MS_INTERNAL_DIR="/data/ms"
fi

if [ -z ${MS_EXTERNAL_DIR} ]; then
  echo "MS_EXTERNAL_DIR is not set - using default /srv/ms"
  MS_EXTERNAL_DIR="/srv/ms"
fi

PROTECT_TMPFS_DIR="/var/opt/unifi-protect/tmp"

if [ "$MS_TMPFS_DIR" != "$PROTECT_TMPFS_DIR" ]; then
  if findmnt -t tmpfs -m ${PROTECT_TMPFS_DIR} 1>&2>/dev/null; then
    echo "ms pre-start:[$@] Unmounting tmpfs at ${PROTECT_TMPFS_DIR}"
    umount ${PROTECT_TMPFS_DIR} || true
  fi
fi

usermod -g ${GROUP} ${USER}

is_link() {
  [ -L "$1" ] && [ -e "$1" ] && return
  false
}

get_disk_space() {
  df "$1" -k | tail -n 1 | awk '{printf $2}'
}

isSrvReadOnly() {
  if ! command -v findmnt &> /dev/null; then
    # ignore if findmnt not found
    return 1
  fi
  # report RO state only if target mounted
  echo "Read Only file system check"
  local TMP=$(findmnt --target /srv -o SOURCE,OPTIONS -n)
  echo $TMP
  echo $TMP | grep -E '^ro$|,ro$|,ro,|^ro,| ro'
  return $?
}

# clean up ems log if too big
clean_up_ms_log() {
  local dir=$1
  local ems_log_path="$dir/logs/ms.00.log"

  local MAX_SIZE=20971520 # 20 MB
  if [ -f $ems_log_path ]; then
    if [ $(stat -c%s $ems_log_path) -gt $MAX_SIZE ]; then
      rm -f $ems_log_path
    fi
  fi
}


if [ -d "/etc" ]; then
  mkdir -p /etc/ms || true
  echo "Changing owner for /etc/ms to $USER:$GROUP"
  chown -R ${USER}:${GROUP} /etc/ms || true
  echo "Setting group permissions for /etc/ms"
  chmod -R ug+rw /etc/ms || true
fi

# External storage available
if (mountpoint -q /srv || is_link /srv) && [ $(get_disk_space /srv) -ge $EXTERNAL_MINIMUM_SPACE ] && (! isSrvReadOnly); then
  if [ ! -d $MS_EXTERNAL_DIR ]; then
    # Create external directory
    echo "Creating external directory $MS_EXTERNAL_DIR"
    mkdir -p "${MS_EXTERNAL_DIR}/logs"
    echo "Changing owner for $MS_EXTERNAL_DIR to $USER:$GROUP"
    chown ${USER}:${GROUP} "${MS_EXTERNAL_DIR}"
    echo "Setting group permissions for $MS_EXTERNAL_DIR"
    chmod -R g+rw "${MS_EXTERNAL_DIR}"
    chown ${USER}:${GROUP} "${MS_EXTERNAL_DIR/logs}"
    echo "Setting group permissions for $MS_EXTERNAL_DIR/logs"
    chmod -R g+rw "${MS_EXTERNAL_DIR/logs}"
    echo "External directory $MS_EXTERNAL_DIR ready"
  fi

  if [ -d $MS_INTERNAL_DIR ]; then
    if [ "$(find ${MS_INTERNAL_DIR}/ -maxdepth 1 -mindepth 1 -type d | wc -l)" -gt 0 ]; then
      # Move internal directory to external directory
      echo "Moving internal directory $MS_INTERNAL_DIR to external directory $MS_EXTERNAL_DIR"
      rsync -a $MS_INTERNAL_DIR/ $MS_EXTERNAL_DIR/
      echo "Removing internal directory $MS_INTERNAL_DIR"
      rm -rf "${MS_INTERNAL_DIR:?}"/*
      echo "Internal directory $MS_INTERNAL_DIR cleaned"
    fi
  fi
else
  if [ ! -d $MS_INTERNAL_DIR ]; then
    echo "Creating internal directory $MS_INTERNAL_DIR"
    mkdir -p "${MS_INTERNAL_DIR}/logs"
    echo "Changing owner for $MS_INTERNAL_DIR to $USER:$GROUP"
    chown ${USER}:${GROUP} "${MS_INTERNAL_DIR}"
    echo "Setting group permissions for $MS_INTERNAL_DIR"
    chmod -R g+rw "${MS_INTERNAL_DIR}"
    chown ${USER}:${GROUP} "$MS_INTERNAL_DIR/logs"
    echo "Setting group permissions for $MS_INTERNAL_DIR/logs"
    chmod -R g+rw "${MS_INTERNAL_DIR}/logs"
    echo "Internal directory $MS_INTERNAL_DIR ready"
  fi
fi

if [ -d ${MS_INTERNAL_DIR} ]; then
  clean_up_ms_log ${MS_INTERNAL_DIR}

  if [ -L $MS_INTERNAL_DIR ]; then
    echo "Changing owner for $MS_INTERNAL_DIR to $USER:$GROUP"
    chown -c -h $USER:$GROUP $MS_INTERNAL_DIR
    echo "Changing owner for $MS_INTERNAL_DIR to $USER:$GROUP"
    chown -c -R $USER:$GROUP $MS_INTERNAL_DIR/ | tail -n 10
  else
    echo "Changing owner for $MS_INTERNAL_DIR to $USER:$GROUP"
    chown -c -R $USER:$GROUP $MS_INTERNAL_DIR | tail -n 10
  fi
  echo "Internal directory $MS_INTERNAL_DIR ready"
fi

if [ -d $MS_EXTERNAL_DIR ]; then
  clean_up_ms_log $MS_EXTERNAL_DIR

  echo "Changing owner for $MS_EXTERNAL_DIR to $USER:$GROUP"
  chown -c $USER:$GROUP $MS_EXTERNAL_DIR
  echo "Changing owner for $MS_EXTERNAL_DIR to $USER:$GROUP"
  chown -c -R $USER:$GROUP $(find $MS_EXTERNAL_DIR -mindepth 1 -maxdepth 1 -type d -printf "%p ") | tail -n 10
  echo "External directory $MS_EXTERNAL_DIR ready"
fi

# Calculate tmpfs size based on system id and mounts it
mount_tmpfs() {
  local os_sysid=$( ubnt-tools id | grep 'board.sysid' | awk -F'=' '{print $2}' )
  local TMPFS_SIZE="2048M"
  local TMPFS_SIZE_DF="2.0G"
  case $os_sysid in
    # 0xeccc - UDR (2GB)
    # 0xa67a - UDR7 (3GB)
    0xeccc|0xa67a)
      TMPFS_SIZE="256M"
      TMPFS_SIZE_DF="${TMPFS_SIZE}"
      ;;
    # 0xa6b9 - UDR 5G Max (3GB)
    # 0xa69a - UCG MAX (3GB)
    # 0xa6a8 - UCG Fiber (3GB)
    # 0xea15 - UDM PRO (4GB)
    # 0xea13 - UDM SE (4GB)
    # 0xea2a - UDW (4GB)
    # 0xea2c - UDM PRO SE (4GB)
    # 0xe970 - UCK G2 Plus (3GB)
    0xe970|0xa69a|0xea15|0xea13|0xea2a|0xea2c|0xa6b9|0xa6a8)
      TMPFS_SIZE="512M"
      TMPFS_SIZE_DF="${TMPFS_SIZE}"
      ;;
    # 0xea32 - UDM PRO MAX (8GB)
    # 0xea16 - UNVR4 (4GB)
    # 0xea1a - UNVR4 (4GB)
    # 0xea20 - UNVR PRO (8GB)
    # 0xa6ad - UCG Industrial (4GB)
    # 0xea61 - UNVR Instant (4GB)
    0xea32|0xea16|0xea1a|0xea20|0xa6ad|0xea61)
      TMPFS_SIZE="1024M"
      TMPFS_SIZE_DF="1.0G"
      ;;
    # 0xea68 - UNVR AI 4 (16GB)
    # 0xea69 - UNVR AI 8 (16GB)
    0xea68|0xea69)
      TMPFS_SIZE="2048M"
      TMPFS_SIZE_DF="2.0G"
      ;;
    # 0xea4c - UDM Beast (32GB)
    # 0xea3f - ENVR (32GB)
    0xea3f|0xea4c)
      TMPFS_SIZE="4096M"
      TMPFS_SIZE_DF="4.0G"
      ;;
    # 0xda28 - ENVR Core (64GB)
    0xda28)
      TMPFS_SIZE="8192M"
      TMPFS_SIZE_DF="8.0G"
      ;;
    *)
      TMPFS_SIZE="2048M"
      TMPFS_SIZE_DF="2.0G"
      ;;
  esac


  if findmnt -t tmpfs -m ${MS_TMPFS_DIR} 1>&2>/dev/null; then
    current_size=$(df -h "${MS_TMPFS_DIR}" | awk 'NR==2 {print $2}')
    if [ "$current_size" != "$TMPFS_SIZE_DF" ]; then
      echo "ms pre-start:[$@] Remounting tmpfs old size ${current_size} with new size ${TMPFS_SIZE} at ${MS_TMPFS_DIR}"
      mount -t tmpfs -o remount,nodev,nosuid,size="${TMPFS_SIZE}",gid="${GROUP}" tmpfs "${MS_TMPFS_DIR}" || true
    else
      echo "ms pre-start:[$@] Tmpfs already mounted with size ${TMPFS_SIZE} at ${MS_TMPFS_DIR}"
    fi
  else 
    echo "ms pre-start:[$@] Mounting tmpfs"

    mkdir -p ${MS_TMPFS_DIR} || true
    echo "Changing owner for $MS_TMPFS_DIR to $USER:$GROUP"
    chown -R ${USER}:${GROUP} ${MS_TMPFS_DIR} || true
    echo "Setting group permissions for $MS_TMPFS_DIR"
    chmod g+rwx ${MS_TMPFS_DIR} || true

    if [ -d ${MS_TMPFS_DIR} ]; then
      echo "ms pre-start:[$@] Remove files from ${MS_TMPFS_DIR} before mounting tmpfs"
      find "${MS_TMPFS_DIR}" -type f -exec rm -f {} + || true
      echo "Files removed from ${MS_TMPFS_DIR}"
    fi

    echo "ms pre-start:[$@] Mounting tmpfs with size ${TMPFS_SIZE} at ${MS_TMPFS_DIR}"
    mount -t tmpfs -o nodev,nosuid,size=${TMPFS_SIZE},gid=${GROUP} tmpfs ${MS_TMPFS_DIR} || true
    echo "Tmpfs mounted with size ${TMPFS_SIZE} at ${MS_TMPFS_DIR}"
  fi
  if [ -d ${MS_TMPFS_DIR} ]; then
    echo "Changing owner for $MS_TMPFS_DIR to $USER:$GROUP"
    chown -R ${USER}:${GROUP} ${MS_TMPFS_DIR} || true
    echo "Setting group permissions for $MS_TMPFS_DIR"
    chmod g+rwx ${MS_TMPFS_DIR} || true
    echo "Removing sticky bits from $MS_TMPFS_DIR"
    chmod a-t ${MS_TMPFS_DIR} || true
    echo "ms pre-start:[$@] Remove files from ${MS_TMPFS_DIR} after mounting tmpfs"
    find "${MS_TMPFS_DIR}" -type f -exec rm -f {} + || true
    echo "Files removed from ${MS_TMPFS_DIR} after mounting tmpfs"
  fi
}

certificates_access() {
  chmod a+r /data/unifi-core/config/unifi-core.crt || true
  chmod a+r /data/unifi-core/config/unifi-core.key || true
}

mount_tmpfs
certificates_access

echo "ms pre-start:[$@] end" >&2
