# Copyright (c) 2018 - 2020 H2O.AI Inc. All rights reserved.

#' daimojo
#' 
#' DAI mojo scoring package
#' 
#' @docType daimojo
#' @import methods
#' @import Rcpp
#' @useDynLib daimojo, .registration=TRUE
#' @name daimojo

setClass("mojo", representation(backend="C++Object"))

#' Load a mojo pipeline
#' 
#' @param filename The mojo file
#' @return The loaded mojo pipeline for futhre usage
#' @examples 
#' \dontrun{
#' m <- load.mojo("pipeline.mojo")
#' }
#' 
#' @export
load.mojo <- function(filnename) {
  if (!file.exists(filnename)) {
    stop("File ", filnename, " not found")
  }
  filnename <- path.expand(filnename)

  m <- new(rcppmojo, filnename, system.file("lib", package="daimojo"))
  
  if (!m$is_valid()) {
    stop("No valid Driverless AI license!")
  }
  
  return(new("mojo", backend=m))
}

#' Creation time of the mojo pipeline
#' 
#' @param m A loaded mojo pipeline
#' @return The creation time of the mojo pipeline
#' @examples 
#' \dontrun{
#' create.time(m)
#' }
#' 
#' @export
create.time <-function(m) {
  if (class(m) != "mojo") {
    stop("not a mojo object!")
  }

  if (!m@backend$is_valid()) {
    stop("No valid Driverless AI license!")
  }

  return(as.POSIXct(m@backend$created_time(), origin="1970-01-01"))
}

#' UUID the experiment generating the mojo pipeline
#' 
#' @param m A loaded mojo pipeline
#' @return The experment UUID
#' @examples 
#' \dontrun{
#' uuid(m)
#' }
#' 
#' @export
uuid <- function(m) {
  if (class(m) != "mojo") {
    stop("not a mojo object!")
  }

  if (!m@backend$is_valid()) {
    stop("No valid Driverless AI license!")
  }

  return(m@backend$uuid())
}

#' Feature names of the mojo pipeline
#' 
#' @param m A loaded mojo pipeline
#' @return A list of feature names
#' @examples 
#' dontrun{
#' feature.names(m)
#' }
#' 
#' @export
feature.names <- function(m) {
  if (class(m) != "mojo") {
    stop("not a mojo object!")
  }

  if (!m@backend$is_valid()) {
    stop("No valid Driverless AI license!")
  }

  return(m@backend$feature_names())
}

#' Feature types of the mojo pipeline
#' 
#' @param m A loaded mojo pipeline
#' @return A list of feature types
#' @examples 
#' dontrun{
#' feature.types(m)
#' }
#' 
#' @export
feature.types <- function(m) {
  if (class(m) != "mojo") {
    stop("not a mojo object!")
  }

  if (!m@backend$is_valid()) {
    stop("No valid Driverless AI license!")
  }

  feature_types <- m@backend$feature_types()
  return(feature_types)
}

#' Output names of the mojo pipeline
#' 
#' @param m A loaded mojo pipeline
#' @return A list of output names
#' @examples
#' dontrun{
#' output.names(m)
#' }
#' 
#' @export
output.names <- function(m) {
  if (class(m) != "mojo") {
    stop("not a mojo object!")
  }

  if (!m@backend$is_valid()) {
    stop("No valid Driverless AI license!")
  }

  return(m@backend$output_names())
}

#' Output types of the mojo pipeline
#' 
#' @param m A loaded mojo pipeline
#' @return A list of output types
#' @examples 
#' dontrun{
#' output.types(m)
#' }
#' 
#' @export
output.types <- function(m) {
  if (class(m) != "mojo") {
    stop("not a mojo object!")
  }

  if (!m@backend$is_valid()) {
    stop("No valid Driverless AI license!")
  }

  output_types <- m@backend$output_types()
  return(output_types)
}

#' Mojo prediction
#' 
#' @param m A loaded mojo pipeline
#' @param newdata A data.frame
#' @return The prediction result
#' @examples 
#' dontrun{
#' m.predict(d)
#' }
#' 
#' @export
predict.mojo <- function(m, newdata) {
  if (class(m) != "mojo") {
    stop("not a mojo object!")
  }

  if (!inherits(newdata, "data.frame")) {
    stop("newdata must be a data.frame")
  }

  if (!m@backend$is_valid()) {
    stop("No valid Driverless AI license!")
  }

  feature_names <- feature.names(m)
  feature_types <- feature.types(m)
  
  newdata <- subset(newdata, ,feature_names)

  for (idx in 1:length(feature_names)) {
    idx <- as.integer(idx)
    if (feature_types[idx] != typeof(newdata[[idx]])) {
      warning(paste("mojo expects col '", feature_names[idx], "' to be ", feature_types[idx],
                    ",", " but ", typeof(newdata[[idx]]), " found.", sep = ""))
      if (feature_types[idx] == "double") {
        newdata[[idx]] <- as.double(newdata[[idx]])
      } else if (feature_types[idx] == "character") {
        newdata[[idx]] <- as.character(newdata[[idx]])
      } else if (feature_types[idx] == "integer") {
        newdata[[idx]] <- as.integer(newdata[[idx]])
      }
    }
  }
  
  return(m@backend$predict(newdata))
}

#' Missing values of the mojo pipeline. Values in this list will be treated as missing during prediction.
#' 
#' @param m A loaded mojo pipeline
#' @return A list of values to be treated as missing.
#' @examples 
#' dontrun{
#' missing.values(m)
#' }
#' 
#' @export
missing.values <- function(m) {
  if (class(m) != "mojo") {
    stop("not a mojo object!")
  }

  if (!m@backend$is_valid()) {
    stop("No valid Driverless AI license!")
  }

  return(m@backend$missing_values())
}

#' Default threshold for binomial problem.
#' 
#' @param m A loaded mojo pipeline
#' @return Default threshold as double.
#' @examples 
#' dontrun{
#' binomial_problem.default_threshold(m)
#' }
#' 
#' @export
binomial_problem.default_threshold <- function(m) {
  if (class(m) != "mojo") {
    stop("not a mojo object!")
  }

  if (!m@backend$is_valid()) {
    stop("No valid Driverless AI license!")
  }

  return(m@backend$binomial_problem_default_threshold())
}

#' Labels for binomial problem.
#' 
#' @param m A loaded mojo pipeline
#' @return Labels array.
#' @examples 
#' dontrun{
#' binomial_problem.labels(m)
#' }
#' 
#' @export
binomial_problem.labels <- function(m) {
  if (class(m) != "mojo") {
    stop("not a mojo object!")
  }

  if (!m@backend$is_valid()) {
    stop("No valid Driverless AI license!")
  }

  return(m@backend$binomial_problem_labels())
}
