# This function load functions from one package locally, as well as the depended
# packages. If the package is not listed in the function but installed in shared path,
# it looks for the depedency and print the packages.
load_local_package <- function(pkg_path, load_depends = TRUE) {

  # Step 0: Solve assumptions
  if (pkg_path %in% c("s2dv", "startR")) {
    pkg_path <- paste0("~/", pkg_path) 
  } else if (pkg_path %in% c("CSTools", "CSIndicators")) {
    pkg_path <- paste0("/esarchive/scratch/aho/git/", tolower(pkg_path))
  } else if (pkg_path %in% c("ClimProjDiags", "multiApply", "easyNCDF", "esviz")) {
    pkg_path <- paste0("/esarchive/scratch/aho/git/", pkg_path)
  }

  # Step 1: Source all the .R files
  path <- paste0(pkg_path, "/R/") # e.g., "/esarchive/scratch/aho/git/cstools/R/"
  f <- list.files(path)
  ff <- lapply(f, function(x) paste0(path, x))
  invisible(lapply(ff,source))
  if (!identical(f, character(0))) {
    message(rep("=", 80))
    message(paste0("Finished souring all the functions under ", path, "."))
    message(rep("=", 80))

  } else {
    stop("No file found.")
  }

  # Step 2: Load all the required libraries
  if (load_depends) {
    pkg_name <- tolower(tail(strsplit(pkg_path, "/")[[1]], 1))
    if (pkg_name == 's2dv') {
      lib <- c("maps", "methods", "abind", "bigmemory", "graphics", "grDevices", "mapproj",
               "parallel", "ClimProjDiags", "stats", "plyr", "ncdf4", "NbClust", "multiApply",
               "SpecsVerification", "easyNCDF", "easyVerification")

    } else if (pkg_name == 'startr') {
      lib <- c("abind", "bigmemory", "future", "multiApply", "parallel", "easyNCDF", "s2dv",
               "ClimProjDiags", "PCICt")

    } else if (pkg_name == 'cstools') {
      lib <- c("maps", "qmap", "easyVerification", "s2dv", "rainfarmr", "multiApply", 
               "ClimProjDiags", "ncdf4", "plyr", "abind", "data.table", "reshape2", "ggplot2",
               "RColorBrewer", "graphics", "grDevices", "stats", "utils", "verification")

    } else if (pkg_name == 'csindicators') {
      lib <- c("multiApply", "s2dv", "stats", "ClimProjDiags")

    } else if (pkg_name == 'climprojdiags') {
      lib <- c("multiApply", "PCICt", "plyr", "climdex.pcic", "stats")

    } else if (pkg_name == 'multiapply') {
      lib <- c("doParallel", "foreach", "plyr")

    } else if (pkg_name == 'easyncdf') {
      lib <- c("ncdf4", "abind")

    } else if (pkg_name == 'esviz') {
      lib <- c("graphics", "grDevices", "maps", "mapproj", "ClimProjDiags", "sf", "ggplot2", "rnaturalearth",
	       "cowplot", "s2dv", "multiApply", "RColorBrewer", "CSTools", "easyNCDF", "dplyr",
	       "plyr", "data.table", "reshape2", "scales")

    } else {  
      all_pkgs_installed <- installed.packages(tail(.libPaths(), 1))
      if (pkg_name %in% tolower(names(all_pkgs_installed[, 1]))) {
        # find the depedency in shared path
        stop("The package's dependency is not defined in the function. Detect depended packages: ", all_pkgs_installed[which(tolower(names(all_pkgs_installed[, 1])) == pkg_name), 5:6])

      } else {
        stop("The package is not defined in the function, and it is not installed in shared library.")
      #lib <- tools::package_dependencies(package)[[1]]
      }
    }

    invisible(lapply(lib, library, character.only = TRUE))

    message(rep("=", 80))
    message(paste0("Finish loading the depended packages: ", paste(lib, collapse = ",")))
    message(rep("=", 80))
  }

}
