#!/bin/bash

[ ! -z "$LI_CONTROLLER_LIB_NETWORK" ] && return 0
LI_CONTROLLER_LIB_NETWORK=true

# create an IP address as an 32 bit unsigned integer
function address() {
    # uid=$1
    # final=$2
    if [ $uid -lt 0 -o $uid -gt 262143 ]
    then
        echo "The UID is outside our working range: $uid" 1>&2
        exit 5
    fi
    printf "0x%08x\n" "$((0x7f000000 + $(($1<<7)) + $2))"
}

# convert an integer IP address to dotted quad format
function dotted_quad() {
    # ADDR=$1
    q3=$(($1 >> 24))
    q2=$(($1 >> 16 & 0xff))
    q1=$(($1 >> 8 & 0xff))
    q0=$(($1 & 0xff))
    echo "$q3.$q2.$q1.$q0"
}

function find_open_ip {
    uid=$1
    uuid=$2
    port=${3:-8080}
    for host_ip in `seq 1 127`
    do
        a=`address $uid $host_ip`
        new_ip=`dotted_quad $a`
        if ! /usr/sbin/lsof -i @${new_ip}:${port} > /dev/null 2>&1
        then
            echo $new_ip
            exit
        fi
    done

    echo "Could not find open IP" 1>&2
    exit 5
}

function embedded_find_open_ip {
    uid=$1
    app_home=$2
    port=${3:-8080}
    for host_ip in `seq 1 127`
    do
        a=`address $uid $host_ip`
        new_ip=`dotted_quad $a`
        # Ensure nothing is listening on new IP
        if ! /usr/sbin/lsof -i @${new_ip}:${port} > /dev/null 2>&1
        then
            # Ensure new IP is available
            if ! grep -q $new_ip $app_home/.env/*_IP
            then 
                echo $new_ip
                exit
            fi
        fi
    done

    echo "Could not find open IP" 1>&2
    exit 5
}


function uid_to_portbegin {
    local uid
    uid=$1

    # Wrappping around the UIDs to manage a discrepency between the
    # stg/prod and dev environment.  Dev should rarely exceed a few
    # hundred uids.  Stg/Prod start allocating at 1000 and go to over
    # 6500 (the wrap UID below) but will stop at 7000.
    wrapuid=$(((65536-${PORT_BEGIN:-35531})/${PORTS_PER_USER:-5}+${UID_BEGIN:-500}))
    while [ $uid -ge $wrapuid ]
    do
        uid=$(($uid - $wrapuid + ${UID_BEGIN:-500}))
    done

    echo $(($(($(($uid-${UID_BEGIN:-500}))*${PORTS_PER_USER:-5}))+${PORT_BEGIN:-35531}))
}

function uid_to_portend {
  uid=$1
  echo $(($(uid_to_portbegin $(($uid + 1)))-1))
}

function uid_to_portset {
  uid=$1
  seq $(uid_to_portbegin $uid) $(uid_to_portend $uid)
}

function uid_to_portrange {
  uid=$1
  echo $(uid_to_portbegin $uid)":"$(uid_to_portend $uid)
}

function uuid_to_portset {
  uuid=$1
  uid=`id -u $uuid`
  if [ $? -ne 0 ]; then
    echo "Cannot resolve uuid" 1>&2
    return 5
  fi
  uid_to_portset $uid
}

function uuid_to_portrange {
  uuid=$1
  uid=`id -u $uuid`
  if [ $? -ne 0 ]; then
    echo "Cannot resolve uuid" 1>&2
    return 5
  fi
  uid_to_portrange $uid
}

function proxy_cmd {
  # Run proxy commands if one exists; otherwise, this is a stub.
  openshift-port-proxy-cfg "${@}"
  return $?
}

function find_next_proxy_port {
  uuid="$1"
  target="$2"

  for proxy_port in $(uuid_to_portset $uuid)
  do
    proxtarg=$(proxy_cmd showproxy "$proxy_port" | awk '{ print $2 }')
    if [ -z "$proxtarg" ]
    then
      proxy_cmd setproxy "$proxy_port" "$target"
      retv=$?
      if [ $retv != 0 ]; then
        echo "Failed to add proxy port"
        return 67
      fi
      echo "$proxy_port"
      return 0
    elif [ "$target" == "$proxtarg" ]
    then
      echo "$proxy_port"
      return 0
    fi
  done
  echo "All ports are taken, cannot add more"
  return 67
}

function remove_proxy_port {
  uuid=$1
  target="$2"

  # This function may be called to clean-up a half-built proxy
  for proxy_port in $(uuid_to_portset $uuid)
  do
    proxtarg=$(proxy_cmd showproxy "$proxy_port" | awk '{ print $2 }')
    if [ "$target" ==  "$proxtarg" ]
    then
      echo "$proxy_port"
      proxy_cmd setproxy "$proxy_port" "delete"
    fi
  done
  return 0
}

function show_proxy_port {
  uuid=$1
  target=$2
  

  for proxy_port in $(uuid_to_portset $uuid)
  do
    proxtarg=$(proxy_cmd showproxy "$proxy_port" | awk '{ print $2 }')
    if [ "$proxtarg" == "$target" ]; then
      echo "$proxy_port"
      return 0
    fi
  done
  echo "Failed to find proxy."
  return 1
}
