@prefix age: <https://ontology.inferal.com/profiles/report-delivery-age/0.1.0/> .
@prefix ms: <https://ontology.inferal.com/profiles/relay-advertising/microsoftads/> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix sh: <http://www.w3.org/ns/shacl#> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .

age:AgePolicyShape a sh:NodeShape ; sh:targetClass age:AgePolicy ;
    rdfs:label "download age policy shape" ;
    rdfs:comment "Requires one explicit timezone-bearing cutoff; supplies no default age policy." ;
    sh:nodeKind sh:IRI ;
    sh:property [ sh:path age:earliestDownloadAt ; sh:minCount 1 ; sh:maxCount 1 ;
        sh:datatype xsd:dateTime ; sh:pattern "^(000[1-9]|00[1-9][0-9]|0[1-9][0-9]{2}|[1-9][0-9]{3})-(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01])T([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9](\\.[0-9]{1,6})?(Z|[+-]((0[0-9]|1[0-3]):[0-5][0-9]|14:00))$" ;
        sh:not [ sh:pattern "\\s" ] ;
        sh:message "A policy needs one valid timezone-bearing xsd:dateTime cutoff in years 0001-9999 with at most six fractional digits." ] .

age:AgeReviewShape a sh:NodeShape ; sh:targetClass age:AgeReview ;
    rdfs:label "download age review shape" ;
    rdfs:comment "Validates review context only. Missing or malformed source downloadedAt values remain assessable and are not constrained by this diagnostic shape." ;
    sh:nodeKind sh:IRI ;
    sh:property [ sh:path age:delivery ; sh:minCount 1 ; sh:maxCount 1 ;
        sh:nodeKind sh:IRI ; sh:class ms:ReportDelivery ] ;
    sh:property [ sh:path age:policy ; sh:minCount 1 ; sh:maxCount 1 ;
        sh:nodeKind sh:IRI ; sh:class age:AgePolicy ; sh:node age:AgePolicyShape ] ;
    sh:property [ sh:path age:evaluatedAt ; sh:minCount 1 ; sh:maxCount 1 ;
        sh:datatype xsd:dateTime ; sh:pattern "^(000[1-9]|00[1-9][0-9]|0[1-9][0-9]{2}|[1-9][0-9]{3})-(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01])T([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9](\\.[0-9]{1,6})?(Z|[+-]((0[0-9]|1[0-3]):[0-5][0-9]|14:00))$" ;
        sh:not [ sh:pattern "\\s" ] ] ;
    sh:sparql [ sh:message "The selected cutoff must not follow the evaluation instant." ;
        sh:select """
            PREFIX age: <https://ontology.inferal.com/profiles/report-delivery-age/0.1.0/>
            SELECT $this WHERE {
                $this age:policy/age:earliestDownloadAt ?cutoff ; age:evaluatedAt ?evaluation .
                FILTER (?cutoff > ?evaluation)
            }
        """ ] .

age:AgeStandingShape a sh:NodeShape ; sh:targetClass age:AgeStanding ;
    rdfs:label "download age standing shape" ;
    rdfs:comment "Closes the four result values for this version of the diagnostic profile." ;
    sh:in ( age:WithinLimit age:TooOld age:Unknown age:FutureDated ) .
