@prefix : <https://cube.link/shape/standalone-cube-constraint#> .
@prefix dash: <http://datashapes.org/dash#> .
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix schema: <http://schema.org/> .
@prefix sh: <http://www.w3.org/ns/shacl#> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
@prefix cube: <https://cube.link/> .
@prefix code: <https://code.described.at/> .

#
# This is the bare minimal SHACL shape for validating a cube.
# All cubes should pass this validation.
#

[
    code:imports <./standalone-constraint-constraint> ;
    code:extension "ttl" ;
] .

:CubeShape
    a sh:NodeShape ;
    sh:targetClass cube:Cube ;
    sh:or
        (
            [
                sh:path schema:name ;
                sh:minCount 1 ;
                sh:datatype xsd:string ;
                sh:message "cube:Cube needs a schema:name"
            ]
            [
                sh:path schema:name ;
                sh:minCount 1 ;
                sh:datatype rdf:langString ;
                sh:message "cube:Cube needs a schema:name"
            ]
        ) ;
    sh:property
        [
            sh:severity sh:Warning ;
            sh:path schema:publisher ;
            sh:minCount 1 ;
            sh:nodeKind sh:IRI ;
            sh:message "cube:Cube needs an schema:publisher"
        ] ;
    sh:property
        [
            sh:severity sh:Warning ;
            sh:path schema:creator ;
            sh:minCount 1 ;
            sh:nodeKind sh:IRI ;
            sh:message "cube:Cube needs an schema:creator"
        ] ;
    sh:property
        [
            sh:path schema:contactPoint ;
            sh:minCount 1 ;
            sh:xone
                (
                    [ sh:nodeKind sh:IRI ]
                    [
                        sh:nodeKind sh:BlankNode ;
                        sh:property
                            [
                                sh:path schema:email ;
                                sh:minCount 1 ;
                                sh:datatype xsd:string ;
                                sh:message "Contact point needs an email"
                            ],
                            [
                                sh:path schema:name ;
                                sh:minCount 1 ;
                                sh:datatype xsd:string ;
                                sh:message "Contact point needs a name"
                            ]
                    ]
                ) ;

            sh:message "cube:Cube needs a schema:contactpoint"
        ] ;
    sh:property
        [
            sh:severity sh:Warning ;
            sh:path schema:contributor ;
            sh:minCount 1 ;
            sh:nodeKind sh:IRI ;
            sh:message "cube:Cube needs an schema:contributor"
        ] ;
    sh:property
        [
            sh:path schema:dateCreated ;
            sh:minCount 1 ;
            sh:datatype xsd:date ;
            sh:message "cube:Cube needs a valid schema:dateCreated"
        ] ;
    sh:property
        [
            sh:path schema:datePublished ;
            sh:minCount 1 ;
            sh:datatype xsd:date ;
            sh:message "cube:Cube needs a valid schema:datePublished"
        ] ;
    sh:property
        [
            sh:path schema:dateModified ;
            sh:or (
                [ sh:datatype xsd:date ]
                [ sh:datatype xsd:dateTime ]
            ) ;
            sh:minCount 1 ;
            sh:message "cube:Cube needs a valid schema:dateModified"
        ] ;
    sh:property
        [
            sh:severity sh:Warning ;
            sh:path cube:observationSet ;
            sh:minCount 1 ;
            sh:node :ObservationSetShape ;
            sh:message "cube:Cube needs an observationSet"
        ] ;
    sh:property
        [
        # optional, but recommended
            sh:path cube:observationConstraint ;
            sh:message "cube:Cube must point to a valid constraint"
        ]
.

:ObservationSetShape
    a sh:NodeShape ;
    sh:targetClass cube:ObservationSet ;
    sh:property
        [
            sh:severity sh:Warning ;
            sh:path cube:observation ;
            sh:minCount 1 ;
            sh:node :ObservationShape ;
            sh:message "cube:Cube needs at least one observation"
        ] ;
.

:ObservationShape
    a sh:NodeShape ;
    sh:targetClass cube:Observation ;
    sh:property
        [
            sh:path cube:observedBy ;
            sh:minCount 1 ;
            sh:nodeKind sh:IRI ;
            sh:message "cube:Observation requires cube:observedBy"
        ] .
