#!/usr/bin/env bash

# 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 <https://www.gnu.org/licenses/>.

# If we fail, we want to fail royally
set -e

PARAMETERS="$(KPopTwist_ "$@")"
if [[ "$PARAMETERS" == "" ]]; then
  exit 1
fi
# We parse the parameters returned by KPopTwist_
OLD_IFS="$IFS"
IFS=$'\x1'
read -r PREFIX_IN SAMPLING_FRACTION THRESHOLD_COUNTS POWER TRANSFORM NORMALIZE THRESHOLD_KMERS PREFIX_OUT THREADS TEMPORARIES VERBOSE <<< "$PARAMETERS"
IFS="$OLD_IFS"

function conditional_echo {
  if [[ "$VERBOSE" == "true" ]]; then
    echo "$1"
  fi
}

# We generate and split the plain text table, so that R can import it
conditional_echo "$(date +"%c"): [1/15] Exporting table..."
TMPDIR=$(mktemp -d -p . KPopTwist-XXXXXXXXXX)
KPopCountDB -T "$THREADS" -i "$PREFIX_IN" --table-threshold "$THRESHOLD_COUNTS" --table-power "$POWER" --table-transform "$TRANSFORM" --table-output-row-names false -t "${TMPDIR}/TABLE" -R "~." -D --table-output-row-names true --table-output-zero-rows true --table-threshold 1. --table-power 1. --table-transform power -t /dev/stdout | tail -n +2 > "${TMPDIR}/NAMES.KPopCounter.txt"

export R_DATATABLE_NUM_PROCS_PERCENT=100
#export R_DATATABLE_THROTTLE=1000000

Rscript --vanilla <(
cat <<'_____'
  library(data.table)
  library(ca)
  args<-commandArgs(trailingOnly=TRUE)
  output<-args[3]
  if (is.na(args[4])||args[4]=="")
    args[4]<-"1."
  fraction<-as.numeric(args[4])
  normalize<-as.logical(args[5])
  threshold<-as.numeric(args[6])
  threads<-as.integer(args[7]) # Not really used at the moment
  temporaries<-as.logical(args[8]) # Not really used at the moment
  verbose<-as.logical(args[9])
  conditional_echo<-function(s){
    if (verbose)
      cat(format(Sys.time(),paste0("%c: ",s,"...\n")))
  }
  conditional_echo("[2/15] Reading names")
  names<-t(data.table::fread(args[2],sep="\t",header=FALSE)) # Why t() would work so much better here is anybody's guess
  conditional_echo("[3/15] Reading counts")
  stuff<-data.table::fread(args[1],sep="\t",header=TRUE)
  conditional_echo("[4/15] Resampling k-mers")
  sampled<-sort(sample(nrow(stuff),as.integer(nrow(stuff)*fraction)))
  names<-names[sampled]
  stuff<-stuff[sampled,]
  conditional_echo("[5/15] Thresholding k-mers")
  sums<-rowSums(stuff)
  sampled<-which(sums>=(max(sums)*threshold))
  names<-names[sampled]
  stuff<-stuff[sampled,]
  conditional_echo("[6/15] Normalizing counts")
  sums<-colSums(stuff)
  if (normalize)
    stuff<-stuff[,Map("/",.SD,data.table::transpose(as.data.table(sums)))]
  conditional_echo("[7/15] Twisting counts")
  stuff_ca<-ca(stuff)
  conditional_echo("[8/15] Writing twisted")
  coords<-cacoord(stuff_ca,cols=TRUE)
  data.table::fwrite(as.data.table(coords,keep.rownames=TRUE),paste0(output,".KPopTwisted.txt"),quote=TRUE,sep="\t",buffMB=64)
  conditional_echo("[9/15] Writing inertia")
  inertia<-t(stuff_ca$sv^2/sum(stuff_ca$sv^2))
  colnames(inertia)<-colnames(coords)
  rownames(inertia)<-c("inertia")
  data.table::fwrite(as.data.table(inertia,keep.rownames=TRUE),paste0(output,".KPopInertia.txt"),quote=TRUE,sep="\t",buffMB=64)
  conditional_echo("[10/15] Normalizing twister")
  twister<-as.data.table(stuff_ca$rowcoord)[,Map("/",.SD,data.table::transpose(as.data.table(stuff_ca$sv)))]
  conditional_echo("[11/15] Transposing twister")
  twister<-data.table::transpose(twister)
  colnames(twister)<-names
  rownames(twister)<-colnames(coords)
  conditional_echo("[12/15] Writing twister")
  data.table::fwrite(twister,paste0(output,".KPopTwister.txt"),row.names=TRUE,quote=TRUE,sep="\t",buffMB=64)
_____
) "${TMPDIR}/TABLE.KPopCounter.txt" "${TMPDIR}/NAMES.KPopCounter.txt" "$PREFIX_OUT" "$SAMPLING_FRACTION" "$NORMALIZE" "$THRESHOLD_KMERS" "$THREADS" "$TEMPORARIES" "$VERBOSE"

# We convert the results to binary form and remove temporary files
conditional_echo "$(date +"%c"): [13/15] Encoding twisted..."
KPopTwistDB -T "$THREADS" -I t "$PREFIX_OUT" -o t "$PREFIX_OUT" > /dev/null 2>&1
conditional_echo "$(date +"%c"): [14/15] Encoding twister..."
KPopTwistDB -T "$THREADS" -I T "$PREFIX_OUT" -o T "$PREFIX_OUT" > /dev/null 2>&1
conditional_echo "$(date +"%c"): [15/15] Cleaning up..."
if [[ "$TEMPORARIES" == "false" ]]; then
  rm "${TMPDIR}/TABLE.KPopCounter.txt" "${TMPDIR}/NAMES.KPopCounter.txt"
  rmdir "${TMPDIR}"
  rm "${PREFIX_OUT}.KPopTwisted.txt" "${PREFIX_OUT}.KPopInertia.txt" "${PREFIX_OUT}.KPopTwister.txt"
fi

conditional_echo "$(date +"%c"): All done."

