#' @title Directed metadata graph construction for SUNSET's Regriding module.
#' @description Generate provenance for the Loading module within a SUNSET workflow.
#' @param recipe Configuration file specifying parameters.
#' @param data s2dv_cube object generated by SUNSET's Loading.R function.
#' @param graph igraph object representing the provenance graph.
#' @return A list containing the updated graph and the name of the parent node.
#' @details This function constructs provenance information for the Loading module within a SUNSET workflow. 
#' It determines the type of interpolation method based on the provided recipe and adds relevant nodes and edges to the graph. 
#' It integrates with other provenance generation functions to create a comprehensive metadata graph.
#' @references https://earth.bsc.es/gitlab/es/sunset/-/tree/Dev-Provenance?ref_type=heads 
#'             Documentation for SUNSET's provenance generation.
#' @references This function is based on the semantics outlined in the Datasource ontology within the 
#'             Metaclip Framework (available at \url{http://www.metaclip.org/}).
#' @import igraph

prov_regridding <- function(recipe, data, graph) {
  #Extract the type from previous nodename + Metadata definitions
  parent.node <- graph$parentnodename
  graph <- graph$graph
  type <- strsplit(parent.node, "_")[[1]][[2]]
  regtype <- recipe$Analysis$Regrid$method
  var <- unlist(strsplit(recipe$Analysis$Variables$name,
                         ",\\s*"))[[1]]

  if (is.null(regtype)) {

    return(list("graph" = graph, "parentnodename" = parent.node))

  }else {
    regtypeclass <- switch(regtype,
                           "nn" = "ds:NearestNeighbor",
                           "bilinear" = "ds:BilinearInterpolation",
                           "bicubic" = "ds:BicubicInterpolation",
                           "distance-weighted" = "ds:InverseDistanceWeighting",
                           "laf" = "ds:InterpolationMethod",
                           "conservative" = "ds:ConservativeRemapping")

    regtype <- switch(regtype,
                      "con2" = "Conservative Remapping",
                      "bilinear" = "Bilinear",
                      "bicubic" = "Bicubic",
                      "distance-weighted" = "Distance Weighting",
                      "laf" = "Spline",
                      "nn" = "Nearest Neighbor")

    #Provenance for a Reggriding operation to the system's grid
    if (recipe$Analysis$Regrid$type == "to_system") {
      refgraph <- get_spatial_extent(data, "hcst", var, Reg = TRUE)
      refgraphnode <- refgraph$parentnodename
      refgraph <- refgraph$graph

      #Interpolation definition
      if (type == "obs") {
        regnodename <- paste0("Interpolation_", type)

        graph <- add_vertices(graph,
                              nv = 1,
                              label = paste(regtype, "interpolation"),
                              name = regnodename,
                              className = "ds:Interpolation",
                              attr = list("dc:description" = "Interpolation to 
                              system, either to forecast or hindcast grid."))

        graph <- add_edges(graph,
                           c(getNodeIndexbyName(graph,
                                                paste0("DatasetSubset_", type)),
                             getNodeIndexbyName(graph, regnodename)),
                           label = "ds:hadInterpolation")

        regmethod.nodename <- paste0("InterpolationMethod_", type)
        graph <- add_vertices(graph,
                              nv = 1,
                              name = regmethod.nodename,
                              label = regtype,
                              className = regtypeclass)

        graph <- add_edges(graph,
                           c(getNodeIndexbyName(graph, regnodename),
                             getNodeIndexbyName(graph, regmethod.nodename)),
                           label = "ds:hadInterpolationMethod")

        #Reference coordinates
        graph <- my_union_graph(graph, refgraph)
        graph <- add_edges(graph,
                           c(getNodeIndexbyName(graph, regnodename),
                             getNodeIndexbyName(graph, refgraphnode)),
                           label = "ds:usedReferenceCoordinates")

        return(list("graph" = graph, "parentnodename" = regnodename))
      }else {

        return(list("graph" = graph, "parentnodename" = parent.node))
      }

      #Provenance for a Reggriding operation to the reference's grid
    }else if (recipe$Analysis$Regrid$type == "to_reference") {
      refgraph <- get_spatial_extent(data, "obs", var, Reg = TRUE)
      refgraphnode <- refgraph$parentnodename
      refgraph <- refgraph$graph

      #Interpolation definition
      if (type == "hcst" || type == "fcst") {
        regnodename <- paste0("Interpolation_", type)
        graph <- add_vertices(graph,
                              nv = 1,
                              label = paste(regtype, "interpolation"),
                              name = regnodename,
                              className = "ds:Interpolation",
                              attr = list("dc:description" = "Interpolation
                              to reference, to the observations grid."))

        graph <- add_edges(graph,
                           c(getNodeIndexbyName(graph,
                                                paste0("DatasetSubset_", type)),
                             getNodeIndexbyName(graph, regnodename)),
                           label = "ds:hadInterpolation")

        regmethod.nodename <- paste0("InterpolationMethod_", type)

        graph <- add_vertices(graph,
                              nv = 1,
                              name = regmethod.nodename,
                              label = regtype,
                              className = regtypeclass)

        graph <- add_edges(graph,
                           c(getNodeIndexbyName(graph, regnodename),
                             getNodeIndexbyName(graph, regmethod.nodename)),
                           label = "ds:hadInterpolationMethod")

        #Reference coordinates
        graph <- my_union_graph(graph, refgraph)

        graph <- add_edges(graph,
                           c(getNodeIndexbyName(graph, regnodename),
                             getNodeIndexbyName(graph, refgraphnode)),
                           label = "ds:usedReferenceCoordinates")

        print(paste0("Dataset provenance computed for ", type))
        return(list("graph" = graph, "parentnodename" = regnodename))

      }else {
        print(paste0("Dataset provenance computed for ", type))
        return(list("graph" = graph, "parentnodename" = parent.node))
      }

    }else if (recipe$Analysis$Regrid$type == "none") {
      print("No interpolation done when loading data")

    #Provenance for a Reggriding operation to a third grid
    }else {
      refgraph <- get_spatial_extent(data, "obs", var, Reg = TRUE)
      refgraphnode <- refgraph$parentnodename
      refgraph <- refgraph$graph

      #Interpolation definition
      if (type == "hcst" || type == "fcst" || type == "obs") {
        regnodename <- paste0("Interpolation_", type)
        graph <- add_vertices(graph,
                              nv = 1,
                              label = paste(regtype, "interpolation"),
                              name = regnodename,
                              className = "ds:Interpolation",
                              attr = list("dc:description"
                                          = paste0(
                                            "Interpolation a 
                                                   grid defined as:",
                                            recipe$Analysis$Regrid$type
                                          )))

        graph <- add_edges(graph,
                           c(getNodeIndexbyName(graph,
                                                paste0("DatasetSubset_", type)),
                             getNodeIndexbyName(graph, regnodename)),
                           label = "ds:hadInterpolation")
        regmethod.nodename <- paste0("InterpolationMethod_", "all")
        graph <- add_vertices(graph,
                              nv = 1,
                              name = regmethod.nodename,
                              label = regtype,
                              className = regtypeclass)
        graph <- add_edges(graph,
                           c(getNodeIndexbyName(graph, regnodename),
                             getNodeIndexbyName(graph, regmethod.nodename)),
                           label = "ds:hadInterpolationMethod")

        #Reference coordinates
        graph <- my_union_graph(graph, refgraph)
        graph <- add_edges(graph,
                           c(getNodeIndexbyName(graph, regnodename),
                             getNodeIndexbyName(graph, refgraphnode)),
                           label = "ds:usedReferenceCoordinates")
      }
      return(list("graph" = graph, "parentnodename" = regnodename))
    }
  }
}
