{
  "$comment": "A JSON schema to validate a FaaSr 2.0 payload, using R library: https://cran.r-project.org/web/packages/jsonvalidate/vignettes/jsonvalidate.html",
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://flare-forecast.org/FaaSr.schema.json",
  "title": "FaaSr  invocation payload",
  "description": "Schema for an invocation of FaaSr",
  "type": "object",
  "properties": {
    "FunctionInvoke": {
      "description": "The name of the function to be invoked by this action",
      "type": "string",
      "minLength": 1
    },
    "InvocationID": {
      "description": "The unique ID used throughout all action invocations for this workflow",
      "type": "string"
    },
    "InvocationTimestamp": {
      "description": "A string that is automatically generated by the workflow's entry point action only and propagated to remaining nodes",
      "type": "string"
    },
    "WorkflowName": {
      "description": "A string that names the workflow for logging purposes - mandatory",
      "type": "string",
      "minLength": 1,
      "pattern": "^[a-zA-Z][a-zA-Z0-9-]*$"
    },
    "InvocationIDFromDate": {
      "description": "An optional strftime format string to derive a unique InvocationID from the InvocationTimestamp (e.g., '%Y%m%d' for daily, '%Y%m%d%H' for hourly)",
      "type": "string",
      "pattern": "^%[YymdHMSjUWaAbBfzZ%-]([%YymdHMSjUWaAbBfzZ%-])*$"
    },
    "LoggingDataStore": {
      "description": "The name of the logging server to use - must match an S3 server defined under DataStores",
      "type": "string"
    },
    "DefaultDataStore": {
      "description": "The name of the default server to use - must match an S3 server defined under DataStores",
      "type": "string",
      "minLength": 1
    },
    "FaaSrLog": {
      "description": "The name of the Log file's folder",
      "type": "string"
    },
    "FunctionRank": {
      "description": "The rank of the current function (optional)",
      "type": "integer"
    },
    "ActionList": {
      "description": "A list of one or more actions that describes the workflow",
      "type": "object",
      "minProperties": 1,
      "propertyNames": {
        "minLength": 1,
        "pattern": "^[a-zA-Z][a-zA-Z0-9-]*$"
      },
      "patternProperties": {
        "": {
          "type": "object",
          "properties": {
            "FaaSServer": {
              "type": "string",
              "minLength": 1
            },
            "FunctionName": {
              "type": "string",
              "minLength": 1,
              "pattern": "^[a-zA-Z_][a-zA-Z0-9_]*$"
            },
            "Arguments": {
              "type": "object"
            },
            "Type": {
              "type": "string",
              "enum": [
                "Python",
                "R"
              ]
            },
            "RequiresVM": {
          "type": "boolean",
          "description": "Whether this action requires VM resources",
          "default": false
        },
        "_faasr_builtin": {
            "type": "boolean",
            "description": "Internal flag: true if this is a framework built-in function"
          },
            "InvokeNext": {
              "type": "array",
              "items": {
                "anyOf": [
                  {
                    "type": "string",
                    "pattern": "^[a-zA-Z][a-zA-Z0-9-]*(?:\\([0-9]+\\))?$"
                  },
                  {
                    "type": "object",
                    "properties": {
                      "True": {
                        "type": "array",
                        "items": {
                          "type": "string",
                          "pattern": "^[a-zA-Z][a-zA-Z0-9-]*(?:\\([0-9]+\\))?$"
                        }
                      },
                      "False": {
                        "type": "array",
                        "items": {
                          "type": "string",
                          "pattern": "^[a-zA-Z][a-zA-Z0-9-]*(?:\\([0-9]+\\))?$"
                        }
                      }
                    },
                    "additionalProperties": false,
                    "minProperties": 1,
                    "maxProperties": 2
                  }
                ]
              },
              "contains": {
                "type": "object",
                "properties": {
                  "True": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "pattern": "^[a-zA-Z][a-zA-Z0-9-]*(?:\\([0-9]+\\))?$"
                    }
                  },
                  "False": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "pattern": "^[a-zA-Z][a-zA-Z0-9-]*(?:\\([0-9]+\\))?$"
                    }
                  }
                },
                "minProperties": 1,
                "maxProperties": 2,
                "additionalProperties": false
              },
              "minContains": 0,
              "maxContains": 1
            },
            "MaxMemory": {
              "type": "number",
              "minimum": 1,
              "description": "Maximum memory needed by the invocation in MB"
            },
            "MaxRuntime": {
              "type": "number",
              "minimum": 1,
              "description": "Maximum runtime needed by the invocation in seconds"
            },
            "MaxStorage": {
              "type": "number",
              "minimum": 1,
              "description": "Maximum local storage needed by the invocation in MB"
            },
            "Resources": {
              "type": "object",
              "description": "Resource requirements for this function",
              "properties": {
                "Nodes": {
                  "type": "integer",
                  "minimum": 1
                },
                "Tasks": {
                  "type": "integer",
                  "minimum": 1
                },
                "CPUsPerTask": {
                  "type": "integer",
                  "minimum": 1
                },
                "Memory": {
                  "type": "integer",
                  "minimum": 1
                },
                "TimeLimit": {
                  "type": "integer",
                  "minimum": 1
                },
                "Partition": {
                  "type": "string"
                },
                "WorkingDirectory": {
                  "type": "string"
                }
              },
              "additionalProperties": false
            }
          },
          "required": [
            "FaaSServer",
            "FunctionName"
          ],
          "additionalProperties": false
        }
      }
    },
    "ComputeServers": {
      "description": "A list of one or more FaaS compute servers used in the workflow",
      "type": "object",
      "minProperties": 1,
      "propertyNames": {
        "minLength": 1
      },
      "patternProperties": {
        "": {
          "type": "object",
          "properties": {
            "FaaSType": {
              "enum": [
                "OpenWhisk",
                "GitHubActions",
                "Lambda",
                "GoogleCloud",
                "SLURM"
              ]
            },
            "Region": {
              "type": "string",
              "minLength": 1
            },
            "Endpoint": {
              "type": "string",
              "minLength": 1
            },
            "SchedulerEndpoint": {
              "type": "string",
              "minLength": 1
            },
            "Namespace": {
              "type": "string",
              "minLength": 1
            },
            "API.key": {
              "type": "string",
              "minLength": 1
            },
            "AccessKey": {
              "type": "string",
              "minLength": 1
            },
            "SecretKey": {
              "type": "string",
              "minLength": 1
            },
            "ClientEmail": {
              "type": "string",
              "minLength": 1
            },
            "TokenUri": {
              "type": "string",
              "minLength": 1
            },
            "UserName": {
              "type": "string",
              "minLength": 1
            },
            "ActionRepoName": {
              "type": "string",
              "minLength": 1
            },
            "Token": {
              "type": "string",
              "minLength": 1
            },
            "Branch": {
              "type": "string"
            },
            "APIVersion": {
              "type": "string"
            },
            "Partition": {
              "type": "string"
            },
            "UseSecretStore": {
              "type": "boolean",
              "default": true,
              "description": "Determines whether to lookup secrets from local secret store (TRUE) or retrieve from payload (FALSE)"
            },
            "SecretsList": {
              "type": "object",
              "description": "A list of SecretName:SecretValue pairs",
              "patternProperties": {
                "": {
                  "type": "string"
                }
              },
              "additionalProperties": false
            },
            "AllowSelfSignedCertificate": {
              "type": "boolean",
              "default": false,
              "description": "Whether to allow self-signed certificates"
            },
            "Nodes": {
              "type": "integer",
              "minimum": 1
            },
            "Tasks": {
              "type": "integer",
              "minimum": 1
            },
            "CPUsPerTask": {
              "type": "integer",
              "minimum": 1
            },
            "Memory": {
              "type": "integer",
              "minimum": 1
            },
            "TimeLimit": {
              "type": "integer",
              "minimum": 1
            },
            "WorkingDirectory": {
              "type": "string"
            },
            "MaxMemory": {
              "type": "number",
              "minimum": 1,
              "description": "Maximum memory for server-level default in MB"
            },
            "MaxRuntime": {
              "type": "number",
              "minimum": 1,
              "description": "Maximum runtime for server-level default in seconds"
            },
            "MaxStorage": {
              "type": "number",
              "minimum": 1,
              "description": "Maximum storage for server-level default in MB"
            }
          },
          "additionalProperties": false,
          "allOf": [
            {
              "if": {
                "properties": {
                  "FaaSType": {
                    "const": "GoogleCloud"
                  }
                },
                "required": [
                  "FaaSType"
                ]
              },
              "then": {
                "required": [
                  "Namespace",
                  "ClientEmail",
                  "TokenUri",
                  "Region"
                ]
              }
            },
            {
              "if": {
                "properties": {
                  "FaaSType": {
                    "const": "OpenWhisk"
                  }
                },
                "required": [
                  "FaaSType"
                ]
              },
              "then": {
                "required": [
                  "Endpoint",
                  "Namespace",
                  "API.key"
                ]
              }
            },
            {
              "if": {
                "properties": {
                  "FaaSType": {
                    "const": "Lambda"
                  }
                },
                "required": [
                  "FaaSType"
                ]
              },
              "then": {
                "required": [
                  "Region"
                ]
              }
            },
            {
              "if": {
                "properties": {
                  "FaaSType": {
                    "const": "GitHubActions"
                  }
                },
                "required": [
                  "FaaSType"
                ]
              },
              "then": {
                "required": [
                  "UserName",
                  "ActionRepoName"
                ]
              }
            },
            {
              "if": {
                "properties": {
                  "FaaSType": {
                    "const": "SLURM"
                  }
                },
                "required": [
                  "FaaSType"
                ]
              },
              "then": {
                "required": [
                  "Endpoint",
                  "UserName",
                  "APIVersion",
                  "Partition"
                ]
              }
            }
          ]
        }
      }
    },
    "DataStores": {
      "description": "A list of one or more S3 data servers used in the workflow",
      "type": "object",
      "minProperties": 1,
      "propertyNames": {
        "minLength": 1
      },
      "patternProperties": {
        "": {
          "type": "object",
          "properties": {
            "Endpoint": {
              "type": "string"
            },
            "AccessKey": {
              "type": "string",
              "minLength": 1
            },
            "SecretKey": {
              "type": "string",
              "minLength": 1
            },
            "Bucket": {
              "type": "string",
              "minLength": 1
            },
            "Region": {
              "type": "string"
            },
            "Writable": {
              "type": "string",
              "minLength": 1
            },
            "Anonymous": {
              "type": "string",
              "minLength": 1
            }
          },
          "required": [
            "Bucket"
          ],
          "additionalProperties": false
        }
      }
    },
    "VMConfig": {
  "type": "object",
  "description": "Configuration for VM orchestration",
  "properties": {
    "Name": {
      "type": "string",
      "minLength": 1,
      "description": "Name of VM configuration"
    },
    "Provider": {
      "type": "string",
      "enum": ["AWS"],
      "description": "Cloud provider for VM instances"
    },
    "InstanceId": {
      "type": "string",
      "description": "Existing EC2 instance ID"
    },
    "Region": {
      "type": "string",
      "description": "AWS region for the VM"
    },
    "AccessKey": {
      "type": "string",
      "description": "AWS access key credential reference"
    },
    "SecretKey": {
      "type": "string",
      "description": "AWS secret key credential reference"
    },
    "RunnerName": {
      "type": "string",
      "description": "Expected GitHub Actions self-hosted runner name"
    }
  },
  "required": ["Name","Provider", "InstanceId", "Region"]
},
    "ActionContainers": {
      "description": "A mapping of action names to containers(Docker Hub)",
      "type": "object",
      "minProperties": 1,
      "propertyNames": {
        "minLength": 1
      },
      "patternProperties": {
        "": {
          "type": "string",
          "minLength": 1
        }
      }
    },
    "FunctionGitRepo": {
      "description": "User code from github Repository",
      "type": "object",
      "minProperties": 1,
      "propertyNames": {
        "minLength": 1
      },
      "patternProperties": {
        "": {
          "type": [
            "string",
            "array"
          ]
        }
      }
    },
    "FunctionLocalFile": {
      "description": "Local file path when function code should be baked into container instead of pulled from repo",
      "type": "object",
      "minProperties": 1,
      "propertyNames": {
        "minLength": 1
      },
      "patternProperties": {
        "": {
          "type": "string",
          "minLength": 1
        }
      }
    },
    "FunctionCRANPackage": {
      "description": "User CRAN packages",
      "type": "object",
      "minProperties": 1,
      "propertyNames": {
        "minLength": 1
      },
      "patternProperties": {
        "": {
          "type": [
            "string",
            "array"
          ]
        }
      }
    },
    "FunctionGitHubPackage": {
      "description": "User packages from github Repository",
      "type": "object",
      "minProperties": 1,
      "propertyNames": {
        "minLength": 1
      },
      "patternProperties": {
        "": {
          "type": [
            "string",
            "array"
          ]
        }
      }
    },
    "PyPIPackageDownloads": {
      "description": "User PyPI packages",
      "type": "object",
      "minProperties": 1,
      "propertyNames": {
        "minLength": 1
      },
      "patternProperties": {
        "": {
          "type": [
            "string",
            "array"
          ]
        }
      }
    },
    "PythonPackageGitHub": {
      "description": "Python packages from GitHub repositories",
      "type": "object",
      "minProperties": 1,
      "propertyNames": {
        "minLength": 1
      },
      "patternProperties": {
        "": {
          "type": [
            "string",
            "array"
          ]
        }
      }
    },
    "PythonCondaPackage": {
      "description": "Python packages from Conda repositories",
      "type": "object",
      "minProperties": 1,
      "propertyNames": {
        "minLength": 1
      },
      "patternProperties": {
        "": {
          "type": [
            "string",
            "array"
          ]
        }
      }
    },
    "RerunOnMatchedInvocationID": {
      "description": "Optional boolean that determines if a user function is re-executed if the workflow has already been executed with the same InvocationID",
      "type": "boolean",
      "default": true
    }
  },
  "required": [
    "FunctionInvoke",
    "WorkflowName",
    "DefaultDataStore",
    "ActionList",
    "ComputeServers",
    "DataStores"
  ]
}

