#!/usr/bin/env bash

# ============================================
# IP Assignment
# ============================================

function ip::assigned() {
  grep -h "^Address" "$(ctx::clients)"/*.conf 2>/dev/null \
    | awk '{print $3}' \
    | cut -d'/' -f1
}

function ip::is_assigned() {
  local candidate="$1"
  ip::assigned | grep -q "^${candidate}$"
}

function ip::next_for_type() {
  local type="$1"
  local subnet
  subnet=$(config::subnet_for "$type")

  if [[ -z "$subnet" ]]; then
    log::error "Unknown device type: ${type}"
    return 1
  fi

  for i in $(seq 1 254); do
    local candidate="${subnet}.${i}"
    if ! ip::is_assigned "$candidate"; then
      echo "$candidate"
      return 0
    fi
  done

  log::error "No available IPs in subnet ${subnet}.0/24"
  return 1
}

# ============================================
# Validation
# ============================================

function ip::is_valid() {
  local ip="$1"
  [[ "$ip" =~ ^([0-9]{1,3}\.){3}[0-9]{1,3}(/([0-9]|[1-2][0-9]|3[0-2]))?$ ]]
}

function ip::is_cidr() {
  [[ "$1" == *"/"* ]]
}

function ip::validate() {
  local ip="$1"
  if ! ip::is_valid "$ip"; then
    log::error "Invalid IP or CIDR: ${ip}"
    return 1
  fi
  return 0
}

function ip::require_valid() {
  local ip="$1"
  ip::validate "$ip" || exit 1
}
