#!/usr/bin/env bash
#
# lib/lvpn-discover
#
# Copyright (c) 2011-2013 LibreVPN <vpn@hackcoop.com.ar>
#
# See AUTHORS for a list of contributors
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation; either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU Affero General
# Public License along with this program.  If not, see
# <http://www.gnu.org/licenses/>.
#
#
# Descubre nodos en la red local y opcionalmente los agrega a connectto
#set -x

. "${LVPN_LIBDIR}"/common

requires avahi-browse base64

TMPDIR="$(mktemp -d /tmp/${NETWORK}-discover-XXXX)"

# Opciones
CONNECTTO=false
FORCE=false
ALL=false
ADD=false
NODES=""
NODE=""
while getopts "hc:fi:a:b:A" arg; do
    case $arg in
        h) help ${self} ; exit 0;;
        c) CONNECTTO=true; ADD=true; NODE=${OPTARG} ;;
        f) FORCE=true ;;
        i) IFACE+="${OPTARG} " ;;
        b) ALL=true; NODE_ACEPT=true; CONNECTTO=true; ADD=true; NODE="${OPTARG}" ;;
        a) ADD=true ; NODE=${OPTARG};;
        A) ALL=true ;;
    esac
done
let OPTIND--; shift ${OPTIND}

# WTF - estoy arreglando esto aunque no se que carajo hace -- fauno
${NODE_ACEPT} && NODE_ACEPT=$1

test -n "${NODE}" && NODEDIR="$(get_node_dir "${NODE}")"

# Si estamos agregando el host pero no tenemos permisos de escritura en
# hosts/, pedimos sudo
if ${ADD} && test ! -w "${LVPN_HOSTS}" ; then
  root=true
  . "${LVPN_LIBDIR}"/common
fi

# Encontrar todas las llaves en _lvpn._udp
# TODO hacer terminate opcional y mantenerlo como un daemon?
avahi-browse --terminate \
             --ignore-local \
             --parsable \
             --resolve \
             _${NETWORK}._udp | grep "^=" | \
grep "$NODE_ACEPT" |\
 while read _s; do
# Interfaz descubierta
    _iface="$(echo "$_s" | cut -d';' -f2)"

# No considerar esta llave si está anunciada dentro de la VPN
    if [ "${_iface}" = "${NETWORK}" ]; then
      ${ALL} || continue
    fi

# Cuando se filtra por interfaz, saltear las que no se especificaron
    if [ ! -z "${IFACE}" ]; then
      echo "${IFACE}" | grep -q "${_iface}" || continue
    fi

# Encontrar el nombre del nodo sin @lvpn
    _node="$(echo "${_s}" | cut -d';' -f4 | sed "s/064${NETWORK}//")"

# No volver a procesar un nodo
    echo "${NODES}" | grep -q "${_node}" && continue

# Generar el archivo de host del nodo descubierto
    echo "${_s}" | cut -d';' -f10 | sed 's/[ "]//g' | \
      base64 -d >"${TMPDIR}/${_node}" 2>/dev/null

# Si estamos agregando
    if ${ADD}; then
      msg "Obteniendo host %s" "${_node}"

# Comprobar si ya tenemos la llave o vamos a confiar en la LAN
      _host_file="$(get_host_file "${_node}")"
      if [ $? -ne 0 ] || ${FORCE} ; then
        msg "Agregando %s" "${_node}"
        cat "${TMPDIR}/${_node}" | ${sudo} tee "${LVPN_HOSTS}/${_node}"
      fi

# CONNECTTO incluye ADD
# TODO hacer esto todo junto requiere cambiar while read por otra cosa
# o tomar los nodos del directorio temporal
      ${CONNECTTO} || ${LVPN} add-host "${NODE}" "${_node}"
      ${CONNECTTO} && ${LVPN} connectto "${NODE}" "${_node}"
    else
# Informar el nombre del nodo
      echo "$_node"
    fi

# Llevar el registro de nodos descubiertos
    NODES+="${_node} "
  done

rm -rf "${TMPDIR}"
exit 0
