# =================================================================
#          #     #                 #     #
#          ##    #   ####   #####  ##    #  ######   #####
#          # #   #  #    #  #    # # #   #  #          #
#          #  #  #  #    #  #    # #  #  #  #####      #
#          #   # #  #    #  #####  #   # #  #          #
#          #    ##  #    #  #   #  #    ##  #          #
#          #     #   ####   #    # #     #  ######     #
#
#       ---   The NorNet Testbed for Multi-Homed Systems  ---
#                       https://www.nntb.no
# =================================================================
#
# High-Performance Connectivity Tracer (HiPerConTracer)
# Copyright (C) 2015-2020 by Thomas Dreibholz
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU 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 General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
#
# Contact: dreibh@simula.no


# ###### Requirements #######################################################

# Up-to-date GNU R installation:
#
# Add to /etc/apt/sources.list:
#    deb https://cran.r-project.org/bin/linux/ubuntu xenial/
#    deb-src https://cran.r-project.org/bin/linux/ubuntu xenial/
# Replace "xenial" by actual Ubuntu variant!
# sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys E084DAB9
# sudo apt-get update
# sudo apt-get dist-upgrade

# Install additional GNU R packages (into user's directory):
#
# options(repos = "https://cran.ms.unimelb.edu.au")
#
# install.packages("mongolite")    # MongoDB access
# install.packages("data.table")   # Efficient handling of big tables
# install.packages("Rcpp")         # Needed by "anytime"; pre-installed version is too old!
# install.packages("anytime")      # time conversion
# install.packages("assertthat")   # assertions
# install.packages("bitops")       # bit operations
# install.packages("openssl")      # base64 encode/decode
#
# update.packages(ask=FALSE)


library("mongolite")
library("data.table")
library("anytime")
library("assertthat")
library("bitops")
library("openssl")

source("nornet-tools.R")


# ====== Connect to MongoDB =================================================
# dbserver   <- "rolfsbukta.alpha.test"
# dbport     <- 27017
# dbuser     <- "researcher"
# dbpassword <- "!researcher!"
# database   <- "pingtraceroutedb"
cafile <- NULL
source("~/.hipercontracer-db-access")

# See https://jeroen.github.io/mongolite/connecting-to-mongodb.html#authentication
options <- ssl_options(weak_cert_validation=FALSE,
                       allow_invalid_hostname=TRUE,
                       ca=cafile)
URL     <- sprintf("mongodb://%s:%s@%s:%d/%s?ssl=true",
                   dbuser, dbpassword, dbserver, dbport, database)
# print(URL)

ping <- mongo("ping", url = URL, options = options)
traceroute <- mongo("traceroute", url = URL, options = options)


# ====== Ping Example =======================================================
cat("###### Ping ######\n")

dateStart <- string_to_unix_time('2018-06-01 11:11:11.000000')
dateEnd   <- string_to_unix_time('2018-06-01 11:11:12.000000')
filterStart <- paste(sep="", '{ "timestamp": { "$gte" : ', sprintf("%1.0f", dateStart), ' } }')
filterEnd   <- paste(sep="", '{ "timestamp": { "$lt" : ',  sprintf("%1.0f", dateEnd), ' } }')
filter <- paste(sep="", '{ "$and" : [ ', filterStart, ', ', filterEnd, ' ] }')
cat(sep="", "Filter: ", filter, "\n")

pingResults <- data.table(ping$find(filter, limit=16))
printPingResults(pingResults)


# ====== Traceroute Example =================================================
cat("###### Traceroute ######\n")

dateStart <- string_to_unix_time('2018-06-01 10:00:00.000000')
dateEnd   <- string_to_unix_time('2018-06-01 10:00:01.000000')
filterStart <- paste(sep="", '{ "timestamp": { "$gte" : ', sprintf("%1.0f", dateStart), ' } }')
filterEnd   <- paste(sep="", '{ "timestamp": { "$lt" : ',  sprintf("%1.0f", dateEnd), ' } }')
filter <- paste(sep="", '{ "$and" : [ ', filterStart, ', ', filterEnd, ' ] }')
cat(sep="", "Filter: ", filter, "\n")

tracerouteResults <- data.table(traceroute$find(filter))
printTracerouteResults(tracerouteResults)


# ====== Ping with Address Search Example ===================================
cat("###### Ping with Address Search ######\n")

dateStart <- string_to_unix_time('2018-02-07 17:07:00.000000')
dateEnd   <- string_to_unix_time('2018-02-07 17:07:02.000000')
address2  <- string_to_base64_ip("172.16.1.2")
address1  <- string_to_base64_ip("fd00:16:1:0:0:0:0:2")

filterStart  <- paste(sep="", '{ "timestamp": { "$gte" : ', sprintf("%1.0f", dateStart), ' } }')
filterEnd    <- paste(sep="", '{ "timestamp": { "$lt" : ',  sprintf("%1.0f", dateEnd), ' } }')
filterA1     <- paste(sep="", '{ "source": { "$type": "0", "$binary": "', address1, '" } }')
filterA2     <- paste(sep="", '{ "source": { "$type": "0", "$binary": "', address2, '" } }')
filterA1orA2 <- paste(sep="", '{ "$or" : [ ', filterA1, ', ', filterA2, ' ] }')
filter <- paste(sep="", '{ "$and" : [ ', filterStart, ', ', filterEnd, ', ', filterA1orA2, ' ] }')
cat(sep="", "Filter: ", filter, "\n")

pingResults <- data.table(ping$find(filter, limit=1000))
printPingResults(pingResults)
