library("tidyverse")
library("gridExtra")
library("patchwork")
library("knitr")
library(RColorBrewer)

r_=function(x){round(x,digits=2)}
color=function(){scale_fill_brewer(palette = "Accent")}
color2=function(){scale_fill_brewer(palette = "Set2")}
nolegend=function(){theme(legend.position="none")}
simkeys=unique(read_csv("results.csv")$simkey)
nsimkeys=length(simkeys)
s_=function(x){if(x<0){return("")}else{return("+")}}
simkey_rename=function(key){
    if(key=="hint")
        return("Hints")
    if(key=="baseline")
        return("Baseline")
    if(key=="extended")
        return("Extended")
    if(key=="hintandextended")
        return("Hints+Extended")
    return(key)
}
dformat=function(data){
    data%>%rowwise()%>%mutate(simkey=simkey_rename(simkey))%>%mutate(wireless=ifelse(wireless=="lora","LoRa","NbIoT"))
}

build_stats=function(file){
data=read_csv(file)
energy60=data%>%filter(wakeupfor==60)
energy60Snd=energy60%>%filter(isSender==1)%>%group_by(simkey,wireless)%>%summarise(sd=sd(energy),energy=mean(energy),type="Sender")
energy60Rcv=energy60%>%filter(isSender==0)%>%group_by(simkey,wireless)%>%summarise(sd=sd(energy),energy=mean(energy),type="Receiver")
energy60=energy60Snd%>%ungroup()%>%rbind(energy60Rcv)
energy60=energy60%>%mutate(sd_min=energy-sd,sd_max=energy+sd)%>%mutate(sd_min_txt=paste0("-",r_(sd_min)))%>%mutate(sd_max_txt=paste0("+",r_(sd_max)))
energy60Baseline=energy60%>%filter(simkey=="baseline")%>%uncount(nsimkeys,.id="id")%>%mutate(simkey=simkeys[id])
energy60=energy60%>%left_join(energy60Baseline,by=c("simkey","wireless","type"),suffix = c("","_baseline"))
energy60=energy60%>%mutate(ovhd=energy*100/energy_baseline-100)
energy60=energy60%>%rowwise()%>%mutate(ovhd_txt=paste0("(",s_(ovhd),r_(ovhd),"%)"))
success60Snd=data%>%filter(wakeupfor==60)%>%filter(isSender!=0)%>%group_by(simkey,wireless,wakeupfor)%>%summarise(success_orig=mean(nSend),success=mean(nSend),type="Sender")
success60Rcv=data%>%filter(wakeupfor==60)%>%filter(isSender!=0)%>%group_by(simkey,wireless,wakeupfor)%>%summarise(success_orig=mean(nSend),success=mean(nSend),type="Receiver")
success60=rbind(success60Snd,success60Rcv)
success60=success60%>%rowwise()%>%mutate(success_txt=paste0("[",success,"]"))
energy60=energy60%>%left_join(success60)%>%rowwise()%>%mutate(infos_txt=paste0(ovhd_txt,"\n{",r_(energy/success_orig),"}"),infos=energy/success_orig)
energy60=energy60%>%mutate(type=factor(type,levels = c("Sender","Receiver")),wakeupfor=60)


energy180=data%>%filter(wakeupfor==180)
energy180Snd=energy180%>%filter(isSender==1)%>%group_by(simkey,wireless)%>%summarise(sd=sd(energy),energy=mean(energy),type="Sender")
energy180Rcv=energy180%>%filter(isSender==0)%>%group_by(simkey,wireless)%>%summarise(sd=sd(energy),energy=mean(energy),type="Receiver")
energy180=energy180Snd%>%ungroup()%>%rbind(energy180Rcv)%>%mutate(type=factor(type,levels = c("Sender","Receiver")))
energy180=energy180%>%mutate(sd_min=energy-sd,sd_max=energy+sd)%>%mutate(sd_min_txt=paste0("-",r_(sd_min)))%>%mutate(sd_max_txt=paste0("+",r_(sd_max)))
energy180Baseline=energy180%>%filter(simkey=="baseline")%>%uncount(nsimkeys,.id="id")%>%mutate(simkey=simkeys[id])
energy180=energy180%>%left_join(energy180Baseline,by=c("simkey","wireless","type"),suffix = c("","_baseline"))
energy180=energy180%>%mutate(ovhd=energy*100/energy_baseline-100)
energy180=energy180%>%rowwise()%>%mutate(ovhd_txt=paste0("(",s_(ovhd),r_(ovhd),"%)"))
success180Snd=data%>%filter(wakeupfor==180)%>%filter(isSender!=0)%>%group_by(simkey,wireless,wakeupfor)%>%summarise(success_orig=mean(nSend),success=mean(nSend),type="Sender")
success180Rcv=data%>%filter(wakeupfor==180)%>%filter(isSender!=0)%>%group_by(simkey,wireless,wakeupfor)%>%summarise(success_orig=mean(nSend),success=mean(nSend),type="Receiver")
success180=rbind(success180Snd,success180Rcv)
success180=success180%>%rowwise()%>%mutate(success_txt=paste0("[",success,"]"))
energy180=energy180%>%left_join(success180)%>%rowwise()%>%mutate(infos_txt=paste0(ovhd_txt,"\n{",r_(energy/success_orig),"}"),infos=energy/success_orig)
energy180=energy180%>%mutate(type=factor(type,levels = c("Sender","Receiver")),wakeupfor=180)

totalUptime60=data%>%filter(wakeupfor==60)
totalUptime60Snd=totalUptime60%>%filter(isSender==1)%>%group_by(simkey,wireless)%>%summarise(sd=sd(totalUptime),totalUptime=mean(totalUptime),type="Sender")
totalUptime60Rcv=totalUptime60%>%filter(isSender==0)%>%group_by(simkey,wireless)%>%summarise(sd=sd(totalUptime),totalUptime=mean(totalUptime),type="Receiver")
totalUptime60=totalUptime60Snd%>%ungroup()%>%rbind(totalUptime60Rcv)%>%mutate(type=factor(type,levels = c("Sender","Receiver")))
totalUptime60=totalUptime60%>%mutate(sd_min=totalUptime-sd,sd_max=totalUptime+sd)%>%mutate(sd_min_txt=paste0("-",r_(sd_min)))%>%mutate(sd_max_txt=paste0("+",r_(sd_max)))
totalUptime60Baseline=totalUptime60%>%filter(simkey=="baseline")%>%uncount(nsimkeys,.id="id")%>%mutate(simkey=simkeys[id])
totalUptime60=totalUptime60%>%left_join(totalUptime60Baseline,by=c("simkey","wireless","type"),suffix = c("","_baseline"))
totalUptime60=totalUptime60%>%mutate(ovhd=totalUptime-totalUptime_baseline)
totalUptime60=totalUptime60%>%rowwise()%>%mutate(ovhd_txt=paste0("(",s_(ovhd),r_(ovhd),")"))
totalUptime60=totalUptime60%>%mutate(type=factor(type,levels = c("Sender","Receiver")),,wakeupfor=60)

totalUptime180=data%>%filter(wakeupfor==180)
totalUptime180Snd=totalUptime180%>%filter(isSender==1)%>%group_by(simkey,wireless)%>%summarise(sd=sd(totalUptime),totalUptime=mean(totalUptime),type="Sender")
totalUptime180Rcv=totalUptime180%>%filter(isSender==0)%>%group_by(simkey,wireless)%>%summarise(sd=sd(totalUptime),totalUptime=mean(totalUptime),type="Receiver")
totalUptime180=totalUptime180Snd%>%ungroup()%>%rbind(totalUptime180Rcv)%>%mutate(type=factor(type,levels = c("Sender","Receiver")))
totalUptime180=totalUptime180%>%mutate(sd_min=totalUptime-sd,sd_max=totalUptime+sd)%>%mutate(sd_min_txt=paste0("-",r_(sd_min)))%>%mutate(sd_max_txt=paste0("+",r_(sd_max)))
totalUptime180Baseline=totalUptime180%>%filter(simkey=="baseline")%>%uncount(nsimkeys,.id="id")%>%mutate(simkey=simkeys[id])
totalUptime180=totalUptime180%>%left_join(totalUptime180Baseline,by=c("simkey","wireless","type"),suffix = c("","_baseline"))
totalUptime180=totalUptime180%>%mutate(ovhd=totalUptime-totalUptime_baseline)
totalUptime180=totalUptime180%>%rowwise()%>%mutate(ovhd_txt=paste0("(",s_(ovhd),r_(ovhd),")"))
totalUptime180=totalUptime180%>%mutate(type=factor(type,levels = c("Sender","Receiver")),wakeupfor=180)

totalUptime=rbind(totalUptime60,totalUptime180)
energy=rbind(energy60,energy180)
totalUptime%>%left_join(energy,by=c("simkey","wireless","wakeupfor","type"),suffix = c("",""))

}

# Load stats
stats=build_stats("results.csv")
stats_prev=build_stats("results_prev.csv")
stats=stats%>%left_join(stats_prev,by=c("simkey","wireless","wakeupfor","type"),suffix=c("","_prev"))

# Additional computations
stats=stats%>%mutate(energy_diff=energy-energy_prev)
stats=stats%>%mutate(success_diff=success-success_prev)
stats=stats%>%mutate(ovhd_diff=ovhd-ovhd_prev)
stats=stats%>%mutate(infos_diff=infos-infos_prev)

# Final results
stats=stats%>%select(simkey,wireless,wakeupfor,type,energy,energy_diff,success_diff,ovhd_diff,infos_diff,ovhd,infos,success)



tf="tables-stats.org"
fw=function(str){write(str,file=tf,append = TRUE)}
df=function(d,rcolor=FALSE){

    if(is.na(d)||is.infinite(d)){
        return("")
    }
    else if(d<0){
        c="green!60"
        if(rcolor){c="red!60"}
        return(paste0(r"(~{\color{)",c,r"(}\textbf{)",r_(d),"}}"))
    }
    else if (d>0){
        c="red!60"
        if(rcolor){c="green!60"}
        return(paste0(r"(~{\color{)",c,r"(}\textbf{+)",r_(d),"}}"))
    }
    r"(~{\color{blue!60}\textbf{=}})"
}
mbox=function(v,d,alpha){
    if(is.infinite(v))
        v="--"
    paste0(r"(\makebox[)",alpha,r"(cm]{\hfill )",v,r"(})",d)
}

write_table=function(techno){
stats%>%filter(wireless==techno)%>%group_by(wakeupfor)%>%group_walk(function(d1,g1){
    uptime=as.numeric(g1)
    first=TRUE
    d1%>%group_by(simkey)%>%group_walk(function(d2,g2){
        scenario=as.character(g2)
        senders=d2%>%filter(type=="Sender")
        receivers=d2%>%filter(type=="Receiver")

        #### Stats
        sender_energy=r_(as.numeric(senders%>%select(energy)))
        receiver_energy=r_(as.numeric(receivers%>%select(energy)))
        sender_ovhd=r_(as.numeric(senders%>%select(ovhd)))
        if(sender_ovhd>0)
            sender_ovhd=paste0("+",sender_ovhd)
        receiver_ovhd=r_(as.numeric(receivers%>%select(ovhd)))
        if(receiver_ovhd>0)
            receiver_ovhd=paste0("+",receiver_ovhd)
        sender_eff=r_(as.numeric(senders%>%select(infos)))
        receiver_eff=r_(as.numeric(receivers%>%select(infos)))
        succ=r_(as.numeric(senders%>%select(success)))

        #### Diff
        sender_energy_diff=df(r_(as.numeric(senders%>%select(energy_diff))))
        receiver_energy_diff=df(r_(as.numeric(receivers%>%select(energy_diff))))
        sender_ovhd_diff=df(r_(as.numeric(senders%>%select(ovhd_diff))))
        receiver_ovhd_diff=df(r_(as.numeric(receivers%>%select(ovhd_diff))))
        sender_eff_diff=df(r_(as.numeric(senders%>%select(infos_diff))))
        receiver_eff_diff=df(r_(as.numeric(receivers%>%select(infos_diff))))
        succ_diff=df(r_(as.numeric(senders%>%select(success_diff))),rcolor = TRUE)
        
        tw=paste0("&",scenario,"&",
                  mbox(succ,succ_diff,0.5),"&",
                  mbox(sender_energy,sender_energy_diff,0.8),"&",
                  mbox(receiver_energy,receiver_energy_diff,0.8),"&",
                  mbox(sender_ovhd,sender_ovhd_diff,0.7),"&",
                  mbox(receiver_ovhd,receiver_ovhd_diff,0.7),"&",
                  mbox(sender_eff,sender_eff_diff,0.65),"&",
                  mbox(receiver_eff,receiver_eff_diff,0.65))


        if(first)
            tw=paste0(r"(\multirow{4}{*}{)",uptime,"}",tw)
        fw(paste0(tw,r"(\\)"))
        
        first<<-FALSE
    })
    if(uptime==60)
        fw(r"(\midrule)")
    })
}

    strategy="shutdown on received"
header=paste0(r"(\begin{table*}
\centering
\caption{)","Simulation results using the ",strategy,r"( strategy. Comparison between our previous results\cite{prev} are in color. Green indicates improvements, red shows regressions and blue indicates no change.)",r"(}
\begin{tabular}{crlllllll}
\toprule
\multirow{2}{*}{Uptime} & \multirow{2}{*}{Scenario} & \multirow{2}{*}{$\# Succ_p$} & \multicolumn{2}{c}{Energy Consumption (J)} & \multicolumn{2}{c}{$eOvhd(p)$ (\%)} & \multicolumn{2}{c}{$eff(p)$ (J)}\\
\cmidrule(lr){4-5}\cmidrule(lr){6-7}\cmidrule(lr){8-9}
&&&Sender & Receiver&Sender & Receiver&Sender & Receiver\\
\midrule)")
footer=r"(\bottomrule
\end{tabular}
\end{table*})"


write("",file=tf)
fw(header)
fw(r"(\multicolumn{9}{c}{LoRa}\\)")
fw(r"(\midrule)")
write_table("lora")
fw(r"(\midrule)")
fw(r"(\multicolumn{9}{c}{NbIoT}\\)")
fw(r"(\midrule)")
write_table("nbiot")
fw(footer)
