#!/bin/bash

Help()
{
   # Display Help
   echo
   echo "tnt-stage takes onionperf input to create a tor_metrics.json file"
   echo "that can then be visualized in tornettools."
   echo
   echo "Please make sure to install:"
   echo "autoconf automake bsdmainutils gcc libevent-dev libssl-dev make"
   echo "python3 python3-pip wget xz-utils zlib1g-dev"
   echo "Syntax: scriptTemplate [-d|m|p|f|o|r|h]"
   echo
   echo "Run with:"
   echo "$ tnt-stage -d <day> -m <year-month> -o <folder> -p <onionperf_data_path> -f <filters> -r <roles>"
   echo "Ex: $ tnt-stage 12 2022-06 data -p ./onionperf_data_path -f filter.txt fast_filter.txt"
   echo
   echo "tnt-stage will create a folder named: data-2022-06-12"
   echo
   echo "options:"
   echo "h     Print this Help."
   echo "p     Provide a path for onionperf.analysis files. "
   echo "      If no path is provided tnt-stage will download the files from"
   echo "      collector.torproject.org for the specified month and date interval"
   echo "f     Specify a list of filters that need to be applied to the"
   echo "      onionperf.analysis files. These will be applied in the same order."
   echo "r     Specify a list of roles for the fingerprint to exclude."
   echo "d     Specify a data day"
   echo "m     Specify a data month"
   echo "o     Specify a data path"
   echo
}

getopts-extra() {
    declare i=1
    # if the next argument is not an option, then append it to array OPTARG
    while [[ ${OPTIND} -le $# && ${!OPTIND:0:1} != '-' ]]; do
        OPTARG[i]=${!OPTIND}
        let i++ OPTIND++
    done
}

while getopts ":hp:f:d:m:o:r:" option; do
   case $option in
      h) # display Help
         Help
         exit;;
      p)
         ONIONPERF_PATH=${OPTARG}
         ;;
      f)
         getopts-extra "$@"
         ONIONPERF_FILTER=( "${OPTARG[@]}" )
         ;;
      d) DATA_DAY=${OPTARG}
         ;;
      m) DATA_MONTH=${OPTARG}
         ;;
      o) DATA_OUT=${OPTARG}
        ;;
      r)
         getopts-extra "$@"
         FILTER_ROLES=( "${OPTARG[@]}" )
         ;;
   esac
done

if [[ ! -v DATA_OUT ]]; then
  DATA_OUT="data"
fi

FOLDER="$DATA_OUT-$DATA_MONTH-$DATA_DAY"

if [[ ! -d "$FOLDER" ]]
then
  mkdir -p $FOLDER
fi
cd $FOLDER


TMODEL_REPO=https://github.com/tmodel-ccs2018/tmodel-ccs2018.github.io.git
TMODEL_BRANCH=master

TOR_REPO=https://gitlab.torproject.org/tpo/core/tor.git
TOR_BRANCH=tor-0.4.7.7

ONIONPERF_REPO=https://gitlab.torproject.org/tpo/network-health/metrics/onionperf.git
ONIONPERF_BRANCH=develop

TORNETTOOLS_REPO=https://github.com/shadow/tornettools.git
TORNETTOOLS_BRANCH=main

if [[ ! -d tmodel ]]
then
  git clone --depth=1 -b $TMODEL_BRANCH $TMODEL_REPO ./tmodel
fi

if [[ ! -d tor ]]
then
  git clone --depth=1 -b $TOR_BRANCH $TOR_REPO ./tor
  cd tor
  mkdir -p opt/tor
  sh autogen.sh
  ./configure --prefix=$(pwd)/opt/tor --disable-asciidoc --disable-dependency-tracking --disable-lzma --disable-zstd
  make -j`nproc`
  make install
  cd ..
fi

if [[ ! -d onionperf ]]
then
  git clone --depth=1 -b $ONIONPERF_BRANCH $ONIONPERF_REPO ./onionperf
fi

if [[ ! -d tornettools ]]
then
  git clone --depth=1 -b $TORNETTOOLS_BRANCH $TORNETTOOLS_REPO ./tornettools
fi

export DATA_DAYS=$(cal -d $DATA_MONTH | awk 'NF {DAYS = $NF}; END {print DAYS}')
export LAST_DATA_DAY=$((DATA_DAY-1))

if [[ ! -d "consensuses-$DATA_MONTH" ]]
then
  wget -O - https://collector.torproject.org/archive/relay-descriptors/consensuses/consensuses-$DATA_MONTH.tar.xz | tar xJ
fi

if [[ ! -d "server-descriptors-$DATA_MONTH" ]]
then
  wget -O - https://collector.torproject.org/archive/relay-descriptors/server-descriptors/server-descriptors-$DATA_MONTH.tar.xz | tar xJ
fi

if [[ ! -f userstats-relay-country.csv ]]
then
  wget https://metrics.torproject.org/userstats-relay-country.csv
fi
USERSTAT_CSV=userstats-relay-country.csv

if [ ! -v ONIONPERF_PATH ]; then
  if [[ ! -d "onionperf-$DATA_MONTH" ]]
  then
    wget -O - https://collector.torproject.org/archive/onionperf/onionperf-$DATA_MONTH.tar.xz | tar xJ
  fi
  cd onionperf-$DATA_MONTH;
  for DAY in `seq -w 01 $LAST_DATA_DAY`; do
    rm -fr $DAY;
  done;
  cd ..
  ONIONPERF_DATA=onionperf-$DATA_MONTH
else
  ONIONPERF_DATA=$ONIONPERF_PATH
fi

if [[ ! -f "bandwidth-$DATA_MONTH.csv" ]]
then
  wget -O bandwidth-$DATA_MONTH.csv "https://metrics.torproject.org/bandwidth.csv?start=$DATA_MONTH-$DATA_DAY&end=$DATA_MONTH-$DATA_DAYS"
fi

BANDWIDTH_CSV=bandwidth-$DATA_MONTH.csv

cd consensuses-$DATA_MONTH;
for DAY in `seq -w 01 $LAST_DATA_DAY`; do
  rm -fr $DAY;
done;
cd ..
CONSENSUSES=consensuses-$DATA_MONTH

cd server-descriptors-$DATA_MONTH;
find . -type f ! -newermt "$DATA_MONTH-$DATA_DAY - 1 second" -delete;
CHECK_ARRAY=( $(find . -type f) );
if [ ${#CHECK_ARRAY[@]} -eq 0 ]; then
    echo "Directory is empty. Stopping";
    exit 1;
fi;
cd ..
SERVER_DESCRIPTORS=server-descriptors-$DATA_MONTH


virtualenv venv

source venv/bin/activate

pip install -r onionperf/requirements.txt
pip install -I onionperf/
pip install -r tornettools/requirements.txt
pip install -I tornettools/
pip install pyparsing

if [ -v ONIONPERF_FILTER ]; then
  echo "Filtering onionperf measurements"
  for i in "${!ONIONPERF_FILTER[@]}"; do
    if [[ -f "${ONIONPERF_FILTER[i]}" ]]; then
      if [ "$i" -eq  "0" ]; then
        if [ -v FILTER_ROLES ]; then
          if [! "${FILTER_ROLES[i]}" eq "fast"]; then
            $FILTER="${FILTER_ROLES[i]}"
            onionperf filter -i $ONIONPERF_DATA -o $ONIONPERF_DATA/filtered-$i --"$FILTER" --exclude-fingerprints ${ONIONPERF_FILTER[i]}
          else
            onionperf filter -i $ONIONPERF_DATA -o $ONIONPERF_DATA/filtered-$i --exclude-fingerprints ${ONIONPERF_FILTER[i]}
          fi
        else
          onionperf filter -i $ONIONPERF_DATA -o $ONIONPERF_DATA/filtered-$i --exclude-fingerprints ${ONIONPERF_FILTER[i]}
        fi
      else
        if [ -v FILTER_ROLES ]; then
          if [! "${FILTER_ROLES[i]}" eq "fast"]; then
            $FILTER="${FILTER_ROLES[i]}"
            onionperf filter -i $ONIONPERF_DATA -o $ONIONPERF_DATA/filtered-$i --"$FILTER" --exclude-fingerprints ${ONIONPERF_FILTER[i]}
          else
            onionperf filter -i $ONIONPERF_DATA -o $ONIONPERF_DATA/filtered-$i --exclude-fingerprints ${ONIONPERF_FILTER[i]}
          fi
        else
          onionperf filter -i $ONIONPERF_DATA -o $ONIONPERF_DATA/filtered-$i --exclude-fingerprints ${ONIONPERF_FILTER[i]}
        fi
      fi
      ONIONPERF_DATA=$ONIONPERF_DATA/filtered-$i
    else
      echo "file ${ONIONPERF_FILTER[i]} doesn't exist"
    fi
  done
else
  echo "No filters to exclude in onionperf measurements ... moving on"
fi

tornettools stage $CONSENSUSES $SERVER_DESCRIPTORS $USERSTAT_CSV tmodel --onionperf_data_path $ONIONPERF_DATA --bandwidth_data_path $BANDWIDTH_CSV --geoip_path tor/opt/tor/share/tor/geoip

deactivate
