#' @title Generate provenance for a SUNSET's Calibration module execution
#' @description Generate provenance information for the execution of a SUNSET's Calibration module.
#' @param recipe Configuration file specifying parameters.
#' @param data s2dv_cube object generated by SUNSET's function Calibration.R.
#' @param graph Provenance graph (igraph object)
#' @param type Type of data: "fcst" for forecast, "hcst" for hindcast, or "obs" for observational data.
#' @return List containing the updated graph and the name of the parent nodes.
#' @details This function generates provenance information for the execution of a SUNSET's Calibration module.
#' @references https://cran.r-project.org/web/packages/CSTools/CSTools.pdf CSTools documentation for CST_Calibration() or CST_QuantileMapping()
#' @references https://earth.bsc.es/gitlab/es/sunset/-/tree/dev-test-provenance?ref_type=heads Documentation for SUNSET's provenance generation.
#' @import igraph

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

  #Define Calibration parameters
  cal <- tolower(recipe$Analysis$Workflow$Calibration$method)
  archive <- read_yaml("conf/variable-dictionary_provenance.yml")
  if (cal %in% names(archive$calibration)) {
    cal.method <- archive$calibration[[cal]]$long_name
    cal.class <- paste0("cal:", archive$calibration[[cal]]$representation)
    cal.description <- archive$calibration[[cal]]$definition
  }else {
    stop("Calibration method not registered or not correctlyy defined")
  }

  if (!(cal == "qmap")) {
    comment <- "For more details, see the  CSTools documentation 
               for CST_Calibration()"
  }else{
    comment <- "For more details, see the  CSTools documentation 
                for CST_QuantileMapping()"
  }
  referenceURL <- "https://cran.r-project.org/web/packages/CSTools/CSTools.pdf"
  reference.nodename <- graph$parentnodename$parentnodename_obs

  #Define last node to which Calibration is applied
  if (type == "fcst" || type == "hcst") {
    i <- switch(type,
                "fcst" = "parentnodename_fcst",
                "hcst" = "parentnodename_hcst")
    parentnodename <- graph$parentnodename[[i]]
    graph <- graph$graph

    #Add Calibration node and vertex
    cal.nodename <- paste0("Calibration_", type)
    graph <- my_add_vertices(graph,
                             name = cal.nodename,
                             label = "Calibration",
                             className = "cal:Calibration")
    graph <- add_edges(graph,
                       c(getNodeIndexbyName(graph, parentnodename),
                         getNodeIndexbyName(graph, cal.nodename)),
                       label = "cal:hadCalibration")

    #Update SpatialExtent
    refgraph <- getSpatialExtent(data, type, Cal = TRUE)
    graph <- my_union_graph(graph, refgraph$graph)
    graph <- add_edges(graph,
                       c(getNodeIndexbyName(graph, cal.nodename),
                         getNodeIndexbyName(graph, refgraph$parentnodename)),
                       label = "ds:hasHorizontalExtent")

    #Add Calibration Method
    calmethod.nodename <- paste0("CalibrationMethod_", "all")
    graph <- my_add_vertices(graph,
                             name = calmethod.nodename,
                             label = cal.method,
                             className = cal.class,
                             attr = list("dc:description" = cal.description,
                                         "dc:comment" = comment,
                                         "ds:referenceURL" = referenceURL))
    graph <- add_edges(graph,
                       c(getNodeIndexbyName(graph, cal.nodename),
                         getNodeIndexbyName(graph, calmethod.nodename)),
                       label = "cal:withCalibrationMethod")
    #Add Reference node
    graph <- add_edges(graph, 
                       c(getNodeIndexbyName(graph, cal.nodename),
                         getNodeIndexbyName(graph, reference.nodename)),
                       label = "cal:withReferenceData")

    print(paste0("Calibration provenance computed for ", type))

    return(list("graph" = graph, "parentnodename" = cal.nodename))
  }else {
    return(list("graph" = graph$graph,
                "parentnodename" = graph$parentnodename$parentnodename_obs))
  }
}