#!/usr/bin/env bash
#
# lib/exec/init
#
# Copyright (c) 2020-     RAP <contacto@partidopirata.com.ar>
# Copyright (c) 2011-2016 LibreVPN <vpn@hackcoop.com.ar>
#
# 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/>.
#
#
# Crea un nuevo nodo

. "${RAP_LIBDIR}"/common

requires tincd

# Opciones
# ConnectTo
connectto=""
# Address
address=""
# Port
port=""
# Instalar
install=false
# Modo verborrágico por defecto
verbose=true
force=false

# Procesar los flags (ver doc)
while getopts 'dvhifp:l:a:c:' arg; do
    case $arg in
        h) help $self; exit 0 ;;
        q) verbose=false ;;
        i) install=true;;
        f) force=true ;;
        p) port="$OPTARG" ;;
        l) localnet="${localnet} $OPTARG" ;;
        a) address="${address} $OPTARG" ;;
        c) connectto="$connectto $OPTARG" ;;
    esac
done ;
let OPTIND--; shift $OPTIND

# Obtener el nombre del host
# Exportamos para post comandos
export NODE="$(get_node_name "${1:-$HOSTNAME}")"

if test -z "${NODE}" ; then
    fatal_error "Se necesita un nombre de nodo"
fi

# Podríamos usar get_node_dir pero chequea si ya existe, cosa que no
nodedir="${RAP_NETWORKSDIR}/${NODE}"
nodefile="${nodedir}/hosts/${NODE}"
conffile="${nodedir}/tinc.conf"

# Con -f se eliminan los archivos anteriores pero se guarda una copia
if $force; then
  rm -rf "${nodefile}~" "${nodedir}~"
  mv "${nodefile}"{,~}
  mv "${nodedir}"{,~}
fi

$verbose && msg "Creando %s..." "*${NODE}*"
if test -f "${nodefile}" ; then
  fatal_error "El nodo ya existe! Utilice -f para re-crearlo"
fi

$verbose && msg "Creando %s..." "*${nodedir}*"
if test -d "${nodedir}" ; then
  fatal_error "El directorio del nodo ya existe"
fi

# Crea los directorios de hosts y scripts
mkdir -p "${nodedir}"/{hosts,scripts} || fatal_error "No se pudo crear el directorio"

$verbose && msg "Generando %s..." "*${nodefile}*"

if test ! -z "${address}" ; then
  for _a in ${address}; do
    add_to_file "${nodefile}" "Address = ${_a}"
  done
else
  $verbose && warning "El nodo no tiene una dirección pública, se configura como nodo privado"
# Cuando no tenemos una dirección pública probablemente estemos detrás
# de un firewall, esto le indica a los demás nodos que no traten de
# conectarse directamente sino que nos envíen paquetes a través de un
# nodo al que estemos conectadxs.
  add_to_file "${nodefile}" "IndirectData = yes"

  PORT=$(until test ${r:-0} -gt 20000; do r=${RANDOM}; done; echo $r)
  $verbose && msg "Utilizando puerto al azar %s" "*${PORT}*"
fi

add_to_file "${nodefile}" "Port = ${port:-${PORT}}"

$verbose && msg "Generando %s..." "*${conffile}*"
add_to_file "${conffile}" "Name = ${NODE}"
add_to_file "${conffile}" "Mode = switch"
add_to_file "${conffile}" "GraphDumpFile = /tmp/${NETWORK}.dot"

# Copiar los scripts de inicio
$verbose && msg "Copiando el resto de archivos..."
ln --symbolic "${RAP_SKELDIR}/run-script" "${nodedir}/run-script"

for s in up down ; do
  ln --symbolic "${RAP_SKELDIR}"/tinc-${s} "${nodedir}"/tinc-${s}
done

$verbose && msg "Añadiendo hosts..."
if test -n "${connectto}" ; then
  ${RAP} connectto ${NODE} ${connectto}
fi

$verbose && msg "Generando llaves..."
echo -e "\n" | tincd -c "${nodedir}" --generate-keys=${KEYSIZE}

$verbose && msg "Guardando el archivo de host con los demás nodos"
mkdir -p "${RAP_HOSTS}"
cp -f "${nodefile}" "${RAP_HOSTS}"

# Instalar el terminar
$install && ${RAP} install ${NODE}

msg "El nodo se ha creado con éxito"

# Chequeamos si hay hook para post comando
run_post_script

exit 0
