#!/bin/sh
# Useful shell utility functions.

# Atomically rewrite a file by writing to a temp file and then renaming it.
# Only rewrites the file if it's different from before.  This helps avoid
# unnecessary flash churn.
atomic() {
  local filename="$1" newval="$2"
  shift

  if [ ! -e $filename ] || [ "$(cat $filename)" != "$newval" ]; then
    rm -f $filename.new
    echo "$@" >$filename.new
    mv $filename.new $filename
  fi
}


# Returns true if the system has wifi.
has_wifi() {
  for d in /sys/class/net/wlan*/address; do
    [ -f "$d" ] && return 0
  done
  if runnable wl; then
    # on boxes with wl, wifi is eth2
    [ -f "/sys/class/net/eth2/address" ] && return 0
  fi
  return 1
}


# Returns true if the string $1 starts with the string $2.
startswith() {
  [ "${1#"$2"}" != "$1" ]
}


# Returns true if the string $1 ends with the string $2.
endswith() {
  [ "${1%$2}" != "$1" ]
}


# Returns true if the string $1 contains the string $2.
contains() {
  case "$1" in
  *"$2"*)
    return 0
  esac
  return 1
}


# Checks if the string $1 is appears in file $2
filecontains() {
  grep "$1" $2 >/dev/null
  [ $? -eq 0 ]
}


export RC_PIPE=/tmp/rc_pipe
rc_pipe_init() {
  if is-tv-box; then
    [ -e $RC_PIPE ] && rm $RC_PIPE
    mknod $RC_PIPE p
    chown root.video $RC_PIPE
    chmod 620 $RC_PIPE # give sage write permissions
    nice babysit 30 soft_rc -i $RC_PIPE 2>&1 | logos softrc &
  fi
}


rc_pipe_deinit() {
    pkillwait -x soft_rc
    rm -f $RC_PIPE
}


setup_mcastcapture_settings() {
  mkdir -p /rw/sagesrv
  chmod 770 /rw/sagesrv
  chown video.video /rw/sagesrv
  chown video.video /rw/sagesrv/*
}


start_sagesrv() {
  setup_mcastcapture_settings
  LD_LIBRARY_PATH=/app/sage:/app/sage/lib
  # Start up native streaming server
  VIDEO_UID=$(id -u video)
  VIDEO_GID=$(id -g video)
  babysit 10 \
  alivemonitor /tmp/sagesrvalive 80 10 120 \
  /app/sage/sagesrv -l6 -m5 -U $VIDEO_UID -G $VIDEO_GID -f 2>&1 \
    | logos z 0 20000000 &
}


stop_sagesrv() {
  pkillwait -f '([b]abysit.*)(sagesrv)'
  pkillwait -x 'sagesrv'
  pkillwait -f '([a]livemonitor.*)(sagesrv)'
}


setup_ads() {
  setup_mcastcapture_settings
  mkdir -p /var/media/ads
  chmod 770 /var/media/ads
  chown video.video /var/media/ads
  chown video.video /var/media/ads/*
  mkdir -p /rw/ads/database
  mkdir -p /rw/ads/contracts
  mkdir -p /rw/ads/cms
  chmod 770 /rw/ads
  chmod 770 /rw/ads/database
  chmod 770 /rw/ads/contracts
  chmod 770 /rw/ads/cms
  chown -R video.video /rw/ads
}


start_adsmgr() {
  setup_ads
  VIDEO_UID=$(id -u video)
  VIDEO_GID=$(id -g video)
  # Start up native ads manager
  babysit 60 \
  alivemonitor /tmp/adsmgralive 80 10 120 \
  /app/sage/adsmgr -U $VIDEO_UID -G $VIDEO_GID 2>&1 | logos ads 0 20000000 &
}


stop_adsmgr() {
  pkillwait -f '([b]abysit.*)(adsmgr)'
  pkillwait -x 'adsmgr'
  pkillwait -f '([a]livemonitor.*)(adsmgr)'
}


start_adscale() {
  setup_mcastcapture_settings
  VIDEO_UID=$(id -u video)
  VIDEO_GID=$(id -g video)
  # Start up native adscale manager
  babysit 60 \
  alivemonitor /tmp/adscalealive 80 10 120 \
  /app/sage/adscale -U $VIDEO_UID -G $VIDEO_GID 2>&1 | logos adscale 0 20000000 &
}


stop_adscale() {
  pkillwait -f '([b]abysit.*)(adscale)'
  pkillwait -x 'adscale'
  pkillwait -f '([a]livemonitor.*)(adscale)'
}


mac_addr_increment() {
  echo "$1" | (
    IFS=: read m1 m2 m3 m4 m5 m6
    m6d=$(printf "%d" "0x$m6")
    m6d=$(($m6d + $2))
    if [ $m6d -ge 256 ]; then
      m6d=$(($m6d - 256))
      m5d=$(printf "%d" "0x$m5")
      m5d=$(($m5d + 1))
      if [ $m5d -ge 256 ]; then
        m5d=$(($m5d - 256))
        m4d=$(printf "%d" "0x$m4")
        m4d=$(($m4d + 1))
        if [ $m4d -ge 256 ]; then
          m4d=$(($m4d - 256))
        fi
        m4=$(printf "%02x" $m4d)
      fi
      m5=$(printf "%02x" $m5d)
    fi
    m6=$(printf "%02x" $m6d)
    echo "$m1:$m2:$m3:$m4:$m5:$m6"
  )
}


# set the locally administered bit on the input mac address and return the
# result (see http://en.wikipedia.org/wiki/MAC_address)
get_locally_administered_mac_addr() {
  echo $1 | {
    IFS=":" read m1 m2 m3 m4 m5 m6
    m1="0x${m1}"
    m1=$((m1 | 0x02))
    printf '%02x:%s:%s:%s:%s:%s\n' $m1 $m2 $m3 $m4 $m5 $m6
  }
}


get_mac_addr_for_interface() {
  cat "/sys/class/net/$1/address" 2> /dev/null
}


find_phy_for_interface() {
  local interface="$1"
  local phy_name=
  iw dev | while read a b junk; do
    if startswith "$a" "phy"; then
      phy_name="$a"
    elif [ "$a" = Interface -a "$b" = "$interface" ]; then
      echo "phy${phy_name#phy\#}"
      break
    fi
  done
}

# Returns true if the given experiment is currently active.
experiment() {
  local expname="$1"
  if [ ! -e "/tmp/experiments/$expname.available" ]; then
    echo "Warning: Experiment '$expname' not registered." >&2
    return 2
  elif [ -e "/config/experiments/$expname.active" ]; then
    echo "Experiment '$expname' active." >&2
    return 0
  else
    return 1
  fi
}

find_sata_blkdev() {
  local dev_node result=

  for dev_node in /dev/sd?; do
    [ -b "$dev_node" ] || continue

    local blkdev=${dev_node#/dev/}
    local dev_path=$(realpath "/sys/block/$blkdev/device")
    if [ "${dev_path#*usb}" = "$dev_path" ]; then
      result="$dev_node"
      break
    fi
  done

  [ -n "$result" ] && echo "$result"
}

find_usb_blkdev() {
  local dev_node result=

  for dev_node in /dev/sd?; do
    [ -b "$dev_node" ] || continue

    local blkdev=${dev_node#/dev/}
    local dev_path=$(realpath "/sys/block/$blkdev/device")
    if contains "$dev_path" "usb"; then
      result="$dev_node"
      break
    fi
  done

  [ -n "$result" ] && echo "$result"
}

interface_exists() {
  [ -e "/sys/class/net/$1" ]
}

is_quantenna_interface() {
  # Check for "$1 " to prevent "wlanX" from matching "wlanX_portal".
  filecontains "$1 " /sys/class/net/quantenna/vlan >/dev/null 2>&1
}

ip46tables() {
  local x y
  iptables "$@"; x=$?
  ip6tables "$@"; y=$?
  return $(($x | $y))
}

# Used by GFSC100. Starts an app with babysit (specified delay) and also logs.
babysit_start() {
  local delay="$1"
  local app="$2"
  local binary="$3"
  local flags="$4"
  if [ -e /tmp/DEBUG ]; then
    # Developer devices save application logs.
    mkdir -p /var/media/applog
    echo "=== $app started ===" >> /var/media/applog/$app
    flags="$flags -v=2"
    babysit $delay $binary $flags 2>&1 | tee -a /var/media/applog/$app | logos $app &
  else
    babysit $delay $binary $flags 2>&1 | logos $app &
  fi
}

platform_megs_ram() {
  n=$(grep MemTotal /proc/meminfo | sed -e 's/MemTotal: *//' -e 's/ kB$//')
  echo $((n / 1024))
}

# Determine whether I2C IO expanders are present based on platform and HW Ver.
# returns 1 if IO expanders are present, 0 if not.
has_i2c_expander() {
  platform=$(cat /etc/platform)
  if [ "$platform" = "GFCH100" ]; then
    if [ -f /etc/hw_ver ]; then
      local CHIMERA_1_2A_HW_VER
      CHIMERA_1_2A_HW_VER=2
      hwver=$(cat /etc/hw_ver)
      if [ $hwver = $CHIMERA_1_2A_HW_VER ]; then
        return 1
      fi
    fi
  fi
  return 0
}

num_sfp_ports() {
  platform=$(cat /etc/platform)
  if [ "$platform" = "GFCH100" ]; then
    if [ -f /etc/hw_ver ]; then
      local CHIMERA_1_2A_HW_VER
      CHIMERA_1_2A_HW_VER=2
      hwver=$(cat /etc/hw_ver)
      if [ $hwver -ge $CHIMERA_1_2A_HW_VER ]; then
        return 2
      fi
    fi
  fi
  return 1
}

set_mac_from_hnvram() {
  local DEV="$1"
  local VAR_NAME="$2"
  if [ -h /sys/class/net/$DEV ]; then
    local addr="$(hnvram -qr "$VAR_NAME")"
    if [ -n "$addr" ]; then
      if is_quantenna_interface $DEV; then
        addr="$(get_locally_administered_mac_addr "$addr")"
      fi
      echo "Setting $DEV mac address to $addr"
      ip link set dev $DEV down
      ip link set dev $DEV address "$addr"
      ip link set dev $DEV up
    else
      echo "$DEV: sysvar $VAR_NAME not found"
    fi
  fi
}
