@prefix : <https://ontology.inferal.com/modules/advertising-delivery-state/> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix rng: <https://ontology.inferal.com/modules/range/> .
@prefix sh: <http://www.w3.org/ns/shacl#> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .

:DeliveryStateShape
    a sh:NodeShape ;
    rdfs:label "delivery state shape" ;
    rdfs:comment "A state must answer the questions separately: which entity, what the advertiser intends, whether it is serving, and its lifecycle standing. Holds are optional, because an entity that is serving has none." ;
    sh:targetClass :DeliveryState ;
    sh:property [
        sh:path :stateOf ;
        sh:name "state of" ;
        sh:minCount 1 ;
        sh:maxCount 1 ;
        sh:nodeKind sh:IRI ;
    ] ;
    sh:property [
        sh:path :intendedDelivery ;
        sh:name "intended delivery" ;
        sh:description "Mandatory. Without it, an entity prevented from delivering is indistinguishable from one the advertiser switched off." ;
        sh:minCount 1 ;
        sh:maxCount 1 ;
        sh:class :DeliveryIntent ;
    ] ;
    sh:property [
        sh:path :observedServing ;
        sh:name "observed serving" ;
        sh:minCount 1 ;
        sh:maxCount 1 ;
        sh:class :ServingState ;
    ] ;
    sh:property [
        sh:path :lifecycleStanding ;
        sh:name "lifecycle standing" ;
        sh:description "Mandatory and separate from intent, so a query for switched-off entities does not return deleted ones. Restricted to the three values this module defines: a provider inventing a fourth standing would not be accounted for by any comparability rule, and a profile aliasing one of the three documents the provider's token rather than supplying a new value." ;
        sh:minCount 1 ;
        sh:maxCount 1 ;
        sh:class :LifecycleState ;
        sh:in ( :liveEntity :archivedEntity :removedEntity ) ;
    ] ;
    sh:property [
        sh:path :heldBy ;
        sh:name "held by" ;
        sh:description "Optional and repeatable: several independent causes can prevent delivery at once." ;
        sh:class :ServingHold ;
    ] ;
    sh:property [
        sh:path :effectiveDuring ;
        sh:name "effective during" ;
        sh:maxCount 1 ;
        sh:class rng:Range ;
    ] .

:ServingHoldShape
    a sh:NodeShape ;
    rdfs:label "serving hold shape" ;
    rdfs:comment "A hold states its kind and where it came from. Both are required: the kind decides who can act, and the origin is what makes an inherited pause traceable to the ancestor responsible instead of leaving an operator to walk the hierarchy." ;
    sh:targetClass :ServingHold ;
    sh:property [
        sh:path :holdKind ;
        sh:name "hold kind" ;
        sh:minCount 1 ;
        sh:maxCount 1 ;
        sh:class :HoldKind ;
    ] ;
    sh:property [
        sh:path :originatingResource ;
        sh:name "originating resource" ;
        sh:description "Mandatory. A hold with no origin cannot be acted on, which is the defect in provider enumerations whose values say an ancestor is paused without naming it." ;
        sh:minCount 1 ;
        sh:maxCount 1 ;
        sh:nodeKind sh:IRI ;
    ] .

:DeliveryIntentShape
    a sh:NodeShape ;
    rdfs:label "delivery intent shape" ;
    rdfs:comment "Intents must be resolvable IRIs so a rule branches on identity rather than a label." ;
    sh:targetClass :DeliveryIntent ;
    sh:nodeKind sh:IRI .

:ServingStateShape
    a sh:NodeShape ;
    rdfs:label "serving state shape" ;
    rdfs:comment "Serving states must be resolvable IRIs for the same reason as intents." ;
    sh:targetClass :ServingState ;
    sh:nodeKind sh:IRI .

:HoldKindShape
    a sh:NodeShape ;
    rdfs:label "hold kind shape" ;
    rdfs:comment "Hold kinds are extended by provider profiles, so being a resolvable IRI keeps the vocabulary navigable." ;
    sh:targetClass :HoldKind ;
    sh:nodeKind sh:IRI .

:LifecycleStateShape
    a sh:NodeShape ;
    rdfs:label "lifecycle state shape" ;
    rdfs:comment "Lifecycle values must be resolvable IRIs. The closed set lives on the delivery state's standing rather than here, because a provider profile may declare a concept aliasing one of the three to carry the provider's own token, and forbidding that would block the pattern every other scheme in this library uses." ;
    sh:targetClass :LifecycleState ;
    sh:nodeKind sh:IRI .
