#' @title Provenance Construction for DatasetSubset
#' @description Generate provenance for a DatasetSubset within the SUNSET framework.
#' @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 a DatasetSubset within SUNSET. 
#' It adds nodes and edges to the provided graph to represent various aspects of the DatasetSubset, 
#' including variables, spatial extents, realizations, and temporal periods.
#' @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 Datasource ontology within the Metaclip Framework (available at \url{http://www.metaclip.org/}).
#' @import igraph

Prov.DatasetSubset <- function(recipe, data, graph) {

  #Extract the type from previous nodename
  parent.node <- graph$parentnodename
  type <- strsplit(parent.node, "_")[[1]][[2]]
  #Add DatasetSubset node
  graph <- graph$graph
  DatasetSubset.nodename <- paste0("DatasetSubset_", type)
  graph <- add_vertices(graph,
                        nv = 1,
                        name = DatasetSubset.nodename,
                        label = "DatasetSubset",
                        className = "ds:DatasetSubset")

  # Link with existing parent node
  graph <- add_edges(graph,
                     c(getNodeIndexbyName(graph, parent.node),
                       getNodeIndexbyName(graph, DatasetSubset.nodename)),
                     label = paste0("ds:hadDatasetSubset"))

  # Add Variable definitions (provenance from the s2dv_cube)
  var.nodename <- paste0("Variable_", type)
  var <- data[[type]]$attr$Variable$varName #Short name
  var.name <- data[[type]]$attr$Variable$metadata[[var]]$long_name #Long name
  if (is.null(var.name)) {
    var.name <- var
  }
  units <- data[[type]]$attr$Variable$metadata[[var]]$units #Units


  graph <- add_vertices(graph,
                        nv = 1,
                        name = var.nodename,
                        label = var.name,
                        className = "ds:Variable",
                        description = "Encode metadata of a Variable",
                        attr = list("ds:withUnits" = units))
                                    #"ds:hasShortName" = var))
                                    #"ds:hasVerticalLevel" = vlevel,
                                    #"ds:hasHorizontalResX" = attr(grd, "resX"),
                                    #"ds:hasHorizontalResY" = attr(grd, "resY"))
                                    #Discuss with Victoria
                                    
  graph <- add_edges(graph,
                     c(getNodeIndexbyName(graph, DatasetSubset.nodename),
                       getNodeIndexbyName(graph, var.nodename)),
                     label = "ds:hasVariable")
  # TemporalResolution
  # VariableStandrardDefinition

  #Add SpatialExtent (Horizontal) node
  refgraph <- getSpatialExtent(data, type)
  graph <- my_union_graph(graph, refgraph$graph)
  graph <- add_edges(graph,
                     c(getNodeIndexbyName(graph, DatasetSubset.nodename),
                       getNodeIndexbyName(graph, refgraph$parentnodename)),
                     label = "ds:hasHorizontalExtent")
  # Add SpatialExtent (Vertical) node
  vextent.nodename <- paste0("VerticalExtent", type)
  graph <- add_vertices(graph,
                        nv = 1,
                        name = vextent.nodename,
                        label = "VerticalExtent",
                        className = "ds:VerticalExtent")

  graph <- add_edges(graph,
                     c(getNodeIndexbyName(graph, DatasetSubset.nodename),
                       getNodeIndexbyName(graph, vextent.nodename)),
                     label = "ds:hasVerticalExtent")
  # Add Realization node
  for(i in 1:length(as.numeric(data[[type]]$coords$ensemble))){
    mem <- paste0("Member_",type, "_", i)
    mem.nodename <- paste0("Realization_", type, "_", i)

    graph <- add_vertices(graph,
                          nv = 1,
                          name = mem.nodename,
                          label = mem,
                          className = "ds:Realization",
                          description = "Encode metadata of Realizations",
                          attr = list("ds:hasMember" = mem))

    graph <- add_edges(graph,
                       c(getNodeIndexbyName(graph, DatasetSubset.nodename),
                         getNodeIndexbyName(graph, mem.nodename)),
                       label = "ds:hasRealization")
  }

  #TemporalInstant

  #Add TemporalPeriod node
  startTime <- list()
  endTime <- list()

  for (i in 1:length(data[[type]]$coords$syear)){
    startTime <- append(startTime, format(data$hcst$attrs$Dates,
                                          format = "%Y-%m-%d %Z")[[i]])
    j <- length(data[[type]]$coords$time) * length(data[[type]]$coords$syear)
    -(length(data[[type]]$coords$syear) - i)
    endTime <- append(endTime, format(data$hcst$attrs$Dates,
                                      format = "%Y-%m-%d %Z")[[j]])
  }
  
  timeper.nodename <- paste0("TemporalPeriod_", type)
  startTime <- paste(startTime, collapse = " ")
  endTime <- paste(endTime, collapse = " ")
  graph <- add_vertices(graph,
                        nv = 1,
                        name = timeper.nodename,
                        label = "TemporalPeriod",
                        className = "ds:TemporalPeriod",
                        description = "Encode metadata of Temporal Periods",
                        attr = list("prov:startedAtTime" = startTime,
                                   "prov:endedAtTime" = endTime))

  graph <- add_edges(graph,
                     c(getNodeIndexbyName(graph, DatasetSubset.nodename),
                       getNodeIndexbyName(graph, timeper.nodename)),
                     label = "ds:hasValidTemporalExtent")

  return(list("graph" = graph, "parentnodename" = DatasetSubset.nodename))
}
