@startuml

class AbstractObject {
  ID string 
  Name string
  IsDraft bool // is consider as a draft
  UpdateDate date 
  LastPeerWriter string 
  CreatorID string 
  AccessMode int // public or private
}

AbstractObject ^-- AbstractResource
AbstractObject ^-- Order
AbstractObject ^-- Booking
AbstractObject ^-- BuyingStatus
AbstractObject ^-- WorkflowExecution
AbstractObject ^-- Workflow

class AbstractResource {
  Logo string 
  Description string 
  ShortDescription string 
  Owners []string 
  UsageRestrictions string 
  
  VerifyAuth(request) bool
}

AbstractResource "1 " --* "many  " ResourceInstanceITF
AbstractCustomizedResource "1  " --* "1  " ResourceInstanceITF

AbstractResource ^-- ComputeResource
AbstractResource ^-- DataResource
AbstractResource ^-- ProcessingResource
AbstractResource ^-- StorageResource
AbstractResource ^-- WorkflowResource
class ComputeResource {
  Architecture string 
  Infrastructure string
}
class DataResource {
  Type string 
  Quality string 
  OpenData bool 
  Static bool 
  UpdatePeriod date 
  PersonalData bool 
  AnonymizedPersonalData bool
  SizeGB float64
  Licence string 
  Example string
}
ProcessingResource "1  " *-- "1  " ProcessingUsage
class ProcessingUsage {
  CPUs map[string]CPU 
  GPUs map[string]GPU 
  RAM RAM
  StorageGB float64 
  Hypothesis string 
  ScalingModel string
}

class ProcessingResource {
  Infrastructure string 
  Service bool 
  Usage ProcessingUsage
  OpenSource bool 
  License string 
  Maturity string 
}
class StorageResource {
  Type string 
  Accronym string
}
WorkflowResource "1  " --* "many  " ComputeResource
WorkflowResource "1  " --* "many  " DataResource
WorkflowResource "1  " --* "many  " ProcessingResource
WorkflowResource "1  " --* "many  " StorageResource
class WorkflowResource {
  WorkflowID string 
}

class ExploitResourceSet {}

AbstractCustomizedResource --^ AbstractResource
AbstractCustomizedResource --* ExploitResourceSet
ExploitResourceSet ^-- CustomizedComputeResource
ExploitResourceSet ^-- CustomizedDataResource
ExploitResourceSet ^-- CustomizedProcessingResource
ExploitResourceSet ^-- CustomizedStorageResource
ExploitResourceSet ^-- CustomizedWorkflowResource
class AbstractCustomizedResource {
// A customized resource is an 
// extended abstract resource not use in catalog
  ExplicitBookingDurationS float64 
  UsageStart date 
  UsageEnd date 
  SelectedPricing string
}
class CustomizedComputeResource {
  CPUsLocated map[string]float64
  GPUsLocated map[string]float64
  RAMLocated float64
}
class CustomizedDataResource {
  StorageGB float64
}
class CustomizedProcessingResource {
  Container Container
}
class CustomizedStorageResource {
  StorageGB bool
}
class CustomizedWorkflowResource {}

interface ResourceInstanceITF {
  GetID() string 
  VerifyPartnership() bool // eval if there is one partnership per peer groups in every instance
  GetPeerGroups() []ResourcePartnerITF, []map[string][]string 
  ClearPeerGroups()
}

ResourceInstanceITF -- ResourceInstance
ResourceInstance ^-- ComputeResourceInstance
ResourceInstance ^-- StorageResourceInstance
ResourceInstance "many  " --* "1  " ResourcePartnerITF
class ResourceInstance {
  ID string 
  Location Geopoint
  Country CountryCode 
  AccessProtocol string 
}
class ComputeResourceInstance {
  SecurityLevel string 
  PowerSource string 
  CPUs map[string]CPU 
  GPUs map[string]GPU 
  RAM RAM
}
class StorageResourceInstance {
  Local bool 
  SecurityLevel string 
  SizeType string 
  SizeGB int 
  Encryption bool 
  Redundancy string 
  Throughput string
}

ResourcePartnerITF -- ResourcePartnership
ResourcePartnership ^-- ComputeResourcePartnership
ResourcePartnership ^-- DataResourcePartnership
ResourcePartnership ^-- StorageResourcePartnership

interface ResourcePartnerITF {
  GetPricing(id string) PricingProfileITF
  GetPeerGroups() []ResourcePartnerITF, []map[string][]string 
  ClearPeerGroups()
}

ResourcePartnership "many  " --*  "1  " PricingProfileITF
class ResourcePartnership{
  Namespace string 
  PeerGroups map[string][]string 
}
class ComputeResourcePartnership {
  MaxAllowedCPUsCores map[string]int 
  MaxAllowedGPUsMemoryGB map[string]float64 
  RAMSizeGB float64
}
class DataResourcePartnership {
  MaxDownloadableGBAllowed float64
  PersonalDataAllowed bool
  AnonymizedPersonalDataAllowed bool
}
class StorageResourcePartnership {
  MaxSizeGBAllowed float64
  OnlyEncryptedAllowed bool
}


RefundType -- AccessPricingProfile
enum RefundType {
  REFUND_DEAD_END
  REFUND_ON_ERROR
  REFUND_ON_EARLY_END
}
PricingProfileITF -- AccessPricingProfile
PricingProfileITF -- ExploitPricingProfile
PricingProfileITF -- WorkflowResourcePricingProfile
AccessPricingProfile ^-- DataResourcePricingProfile
AccessPricingProfile ^-- ProcessingResourcePricingProfile
ExploitPricingProfile ^-- ComputeResourcePricingProfile
ExploitPricingProfile ^-- StorageResourcePricingProfile
interface PricingProfileITF {
  GetPrice(quantity float64, val float64, start date, end date, request) float64
  IsPurchased() bool
}
class AccessPricingProfile {
  ID string 
  Pricing PricingStrategy
  DefaultRefundType RefundType 
  RefundRatio int // percentage of refund on price
}
class DataResourcePricingProfile {}
class ProcessingResourcePricingProfile {}

ExploitPrivilegeStrategy -- ExploitPricingProfile
enum ExploitPrivilegeStrategy {
  BASIC
  GARANTED_ON_DELAY
  GARANTED
} 

AccessPricingProfile --* PricingStrategy
AccessPricingProfile ^-- ExploitPricingProfile
class ExploitPricingProfile {
  AdditionnalRefundTypes RefundTypeint 
  PrivilegeStrategy ExploitPrivilegeStrategy 
  GarantedDelaySecond int 
  Exceeding bool 
  ExceedingRatio int // percentage of Exceeding based on price
}
class ComputeResourcePricingProfile {
  OverrideCPUsPrices map[string]float64
  OverrideGPUsPrices map[string]float64
  OverrideRAMPrice float64
}
class StorageResourcePricingProfile {}
WorkflowResourcePricingProfile "1  " --* "many  " ExploitResourceSet

class WorkflowResourcePricingProfile {
  ID string 
}

BuyingStrategy -- PricingStrategy
enum BuyingStrategy {
  UNLIMITED 
  SUBSCRIPTION 
  PAY_PER_USE
}
Strategy -- TimePricingStrategy
Strategy "0-1  " *-- " " PricingStrategy
interface Strategy {
  GetStrategy () string 
  GetStrategyValue() int
}
enum TimePricingStrategy {
  ONCE 
  PER_SECOND 
  PER_MINUTE
  PER_HOUR
  PER_DAY
  PER_WEEK
  PER_MONTH
}

class PricingStrategy {
  Price float64 
  BuyingStrategy 
  TimePricingStrategy TimePricingStrategy
  OverrideStrategy Strategy
}


PeerOrder "many  " *-- "1  " Order
PeerItemOrder "many  " *-- "1  " PeerOrder
PricedItemITF "many  " *-- "1  " PeerItemOrder

PricedItemITF -- AbstractCustomizedResource

class Order {
  OrderBy string 
  WorkflowExecutionIDs []string
  Status string 
  Total float64
}
class PeerOrder {
  PeerID string 
  Error string 
  Status string 
  BillingAddress string 
  Total float64
}
class PeerItemOrder {
  Quantity int 
  BuyingStatus string 
}

class BuyingStatus {}

WorkflowExecution "many  " --* "1  " Workflow
Workflow "1  " --* "many  " WorkflowScheduler
WorkflowScheduler "1  " --* "many  " WorkflowExecution

class WorkflowExecution {
  ExecDate date 
  EndDate date 
  State string 
  WorkflowID string 
  
  ToBookings() []Booking
}
class WorkflowScheduler* {
  Message string 
  Warning string 
  Start date 
  End date 
  DurationS float64
  Cron string
  
  Schedules(workflowID string, request) []WorkflowExecution
}


Workflow "1  " --* "many  " ExploitResourceSet

class Workflow {}

interface PricedItemITF {
  getPrice(request) float64, error
}

@enduml