#' @title Generate provenance for Visualization computation
#' @description Generate provenance information for Visualization
#' module in SUNSET based on forecast verification.
#' @param recipe Configuration file specifying parameters.
#' @param data s2dv_cube object generated by SUNSET's Loading.R function.
#' @param graph Graph object containing provenance information.
#' @param type Type of data: "fcst" for forecast, "hcst" for
#' hindcast, or "obs" for observational data.
#' @return List containing updated graph and parent node name.
#' @details This function generates provenance information for
#' the computation of graphs in SUNSET.
#' @import igraph
#' @references https://earth.bsc.es/gitlab/es/sunset/-/
#' tree/dev-test-provenance?ref_type=heads
#' Documentation for SUNSET's provenance generation.
#' @references This function is based on the semantics outlined
#' in the Graphical Output ontology within the Metaclip Framework
#' (available at \url{http://www.metaclip.org/}).
library(stringr)

Prov.Visualization <- function(recipe, data, graph, type, outdirs) {
  #Define parameters
  plots <- strsplit(recipe$Analysis$Workflow$Visualization$plots, ", | |,")[[1]]
  i <- switch(type,
              "fcst" = "parentnodename_fcst",
              "hcst" = "parentnodename_hcst")
  parentnodename <- graph$parentnodename[[i]]
  graph <- graph$graph
  #Skill metrics graph nodes

  if ("skill_metrics" %in% plots) {
    measure <- unlist(strsplit(recipe$Analysis$Workflow$Skill$metric, " "))
    nodenames <- list()
    for (names in measure){
      graph.plot <- graph
      names <- tolower(names)
      graph.nodename <- paste0("Graph_", type, "_", names)
      label.name <- names
      graph.path <- list()

      for (i in 1:length(outdirs)) {
        if (names %in% as.list(unlist(strsplit(outdirs[[i]], "[/-]"))) ||
              names %in% as.list(unlist(strsplit(outdirs[[i]], "[/.]")))) {
          graph.path <- append(graph.path, outdirs[[i]]) #All graph paths
        }
      }
      #Graphical representation node
      if (!is.null(recipe$Analysis$Workflow$Visualization$projection)) {
        projection <- recipe$Analysis$Workflow$Visualization$projection
      }else {
        projection <- "Cylindrical equidistant"
      }
      graph.plot <-
        add_vertices(graph.plot,
                     nv = 1,
                     name = graph.nodename,
                     label = paste0(label.name, " ",
                                    "Graphical representation"),
                     className = "go:Map",
                     description = "A Map class object",
                     attr = list("go:hasProjection" = projection,
                                 "prov:AtLocation" =
                                   paste(unlist(graph.path),
                                         collapse = " ")))

      #Link graph node with Skill that plots
      graph.plot <- add_edges(graph.plot,
                         c(getNodeIndexbyName(graph.plot,
                                              paste0("Metrics_", type,
                                                     "_", names)),
                           getNodeIndexbyName(graph.plot, graph.nodename)),
                         label = "go:hadGraphicalRepresentation")

      nodenames <- append(nodenames, list(graph.nodename))

      graph.plot <-
        SunsetProv.Command(graph.plot, package = "Visualization",
                           version = "2.0.0",
                           fun = "modules/Visualization/Visualization.R",
                           arg.list =
                           list(
                                "Recipe",
                                "Data"),
                           origin.node.name
                           = c(
                               unlist(
                                      graph.nodename)))

      #Embbed provenance to the generated image files
      for (paths in graph.path) {
        path.json <- paste0(str_sub(paths, 1, -4), "json")
        graph2json(graph.plot, path.json)
        embedJSON(paths, path.json, paths)
      }
      graph.full <- my_union_graph(graph.plot, graph)


    }
  }

  #Forecast ensemble graph node
  if (!is.null(data$fcst)) {
    if ("forecast_ensemble_mean" %in% plots) {
      graph.nodename <- paste0("Graph_", "forecast_ensemble")
      graph.path <- list()
      for (i in 1:length(outdirs)) {
        if ("forecast_ensemble_mean"
            %in%
              as.list(unlist(strsplit(outdirs[[i]], "[/-]")))) {
          graph.path <- append(graph.path, outdirs[[i]])
        }
      }
      graph.plot <- graph
      graph.plot <-
        add_vertices(graph.plot,
                     nv = 1,
                     name = graph.nodename,
                     label = paste0("Forecast Ensemble",
                                    "Graphical representation"),
                     className = "go:Map",
                     attr = list("prov:AtLocation" =
                                   paste(unlist(graph.path),
                                         collapse = " ")))

      lastnode <- list("Anomalies_fcst", "Calibration_fcst",
                       "DatasetSubset_fcst", "Interpolation_fcst")
      lastnode <- keep_latest_node(lastnode, graph.plot)
      graph.plot <- add_edges(graph.plot,
                              c(getNodeIndexbyName(graph.plot, lastnode),
                                getNodeIndexbyName(graph.plot, graph.nodename)),
                              label = "go:hadGraphicalRepresentation")

      nodenames <- append(nodenames, list(graph.nodename))

      graph <-
        SunsetProv.Command(graph.plot, package = "Visualization",
                           version = "2.0.0",
                           fun = "modules/Visualization/Visualization.R",
                           arg.list =
                           list(
                                "Recipe",
                                "Data"),
                           origin.node.name
                           = c(
                               unlist(
                                      graph.nodename)))   
      for (paths in graph.path) {
        graph2json(graph.plot, path.json)
        embedJSON(paths, path.json, paths)

      }
      graph.full <- my_union_graph(graph.plot, graph)
    }
  }
  return(list("graph" = graph.full,
              "parentnodename" = parentnodename, "nodenames" = nodenames))

}
