@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
@prefix sh: <http://www.w3.org/ns/shacl#> .
@prefix uco-core: <https://ontology.unifiedcyberontology.org/uco/core/> .
@prefix uco-location: <https://ontology.unifiedcyberontology.org/uco/location/> .
@prefix cacontology-production: <https://cacontology.projectvic.org/production#> .
@prefix gufo: <http://purl.org/nemo/gufo#> .
@prefix cacontology: <https://cacontology.projectvic.org#> .
@prefix owl: <http://www.w3.org/2002/07/owl#> .
@prefix dcterms: <http://purl.org/dc/terms/> .
@prefix cac-core: <https://cacontology.projectvic.org/core#> .

# Ontology Declaration
<https://cacontology.projectvic.org/production/shapes/3.0.0> rdf:type owl:Ontology ;
    rdfs:label "CAC Production SHACL Shapes with gUFO Validation"@en ;
    rdfs:comment "SHACL validation shapes for gUFO-enhanced CAC production ontology, including anti-rigidity constraints, temporal validation, and foundational type compliance."@en ;
    owl:versionIRI <https://cacontology.projectvic.org/production/shapes/3.0.0> ;
    owl:versionInfo "3.0.0" ;
    dcterms:creator "CAC Ontology Team" ;
    dcterms:modified "2025-11-18"^^xsd:date ;
    owl:imports <https://cacontology.projectvic.org/production/3.0.0> ,
                <http://purl.org/nemo/gufo#> ,
                <https://ontology.unifiedcyberontology.org/uco/core/> .

# =============================================================================
# gUFO PHASE VALIDATION SHAPES
# =============================================================================

cacontology-production:ProductionPhaseShape rdf:type sh:NodeShape ;
    sh:targetClass cac-core:Phase ;
    rdfs:label "Production Phase Shape"@en ;
    rdfs:comment "gUFO-enhanced validation shape for production phases with anti-rigidity constraints."@en ;
    sh:property [
        sh:path cacontology-production:hasProductionPhaseBeginPoint ;
        sh:datatype xsd:dateTimeStamp ;
        sh:minCount 0 ;
        sh:maxCount 1 ;
        sh:message "Production phase may have at most one begin point."@en
    ] ;
    sh:property [
        sh:path cacontology-production:hasProductionPhaseEndPoint ;
        sh:datatype xsd:dateTimeStamp ;
        sh:minCount 0 ;
        sh:maxCount 1 ;
        sh:message "Production phase may have an end point."@en
    ] ;
    sh:sparql [
        sh:message "Phase begin point must be before end point."@en ;
        sh:prefixes [
            sh:declare [
                sh:prefix "cacontology-production" ;
                sh:namespace "https://cacontology.projectvic.org/production#"^^xsd:anyURI
            ]
        ] ;
        sh:select """
            PREFIX cacontology-production: <https://cacontology.projectvic.org/production#>
            SELECT ?this WHERE {
                ?this cacontology-production:hasProductionPhaseBeginPoint ?begin .
                ?this cacontology-production:hasProductionPhaseEndPoint ?end .
                FILTER(?begin >= ?end)
            }
        """
    ] ;
    sh:sparql [
        sh:message "Phase instances must be anti-rigid (cannot exist without being instantiated by entities)."@en ;
        sh:prefixes [
            sh:declare [
                sh:prefix "gufo" ;
                sh:namespace "http://purl.org/nemo/gufo#"^^xsd:anyURI
            ]
        ] ;
        sh:select """
            PREFIX gufo: <http://purl.org/nemo/gufo#>
            PREFIX owl: <http://www.w3.org/2002/07/owl#>
            SELECT ?this WHERE {
                ?this a gufo:Phase .
                FILTER NOT EXISTS { ?this a owl:Class . }
                FILTER NOT EXISTS { 
                    ?entity ?property ?this .
                    ?property rdfs:subPropertyOf* gufo:hasPhase .
                }
            }
        """
    ] .

cacontology-production:ActiveProductionPhaseShape rdf:type sh:NodeShape ;
    sh:targetClass cacontology-production:ActiveProductionPhase ;
    rdfs:label "Active Production Phase Shape"@en ;
    rdfs:comment "Validation for active production phase instances."@en ;
    sh:property [
        sh:path cacontology-production:productionActivity ;
        sh:datatype xsd:string ;
        sh:minCount 1 ;
        sh:maxCount 1 ;
        sh:in ( "recording" "editing" "streaming" "distribution_preparation" ) ;
        sh:message "Active production phase must specify current production activity."@en
    ] .

# =============================================================================
# gUFO ROLE VALIDATION SHAPES
# =============================================================================

cacontology-production:ProductionRoleShape rdf:type sh:NodeShape ;
    sh:targetClass cac-core:Role ;
    rdfs:label "Production Role Shape"@en ;
    rdfs:comment "gUFO-enhanced validation shape for production roles with anti-rigidity and temporal constraints."@en ;
    sh:property [
        sh:path cacontology-production:hasRoleBeginPoint ;
        sh:datatype xsd:dateTimeStamp ;
        sh:minCount 0 ;
        sh:maxCount 1 ;
        sh:message "Production role may have at most one begin point."@en
    ] ;
    sh:property [
        sh:path cacontology-production:hasRoleEndPoint ;
        sh:datatype xsd:dateTimeStamp ;
        sh:minCount 0 ;
        sh:maxCount 1 ;
        sh:message "Production role may have an end point."@en
    ] ;
    sh:sparql [
        sh:message "Role begin point must be before end point."@en ;
        sh:prefixes [
            sh:declare [
                sh:prefix "cacontology-production" ;
                sh:namespace "https://cacontology.projectvic.org/production#"^^xsd:anyURI
            ]
        ] ;
        sh:select """
            PREFIX cacontology-production: <https://cacontology.projectvic.org/production#>
            SELECT ?this WHERE {
                ?this cacontology-production:hasRoleBeginPoint ?begin .
                ?this cacontology-production:hasRoleEndPoint ?end .
                FILTER(?begin >= ?end)
            }
        """
    ] ;
    sh:sparql [
        sh:message "Role instances must be anti-rigid (cannot exist without being played by entities)."@en ;
        sh:prefixes [
            sh:declare [
                sh:prefix "gufo" ;
                sh:namespace "http://purl.org/nemo/gufo#"^^xsd:anyURI
            ]
        ] ;
        sh:select """
            PREFIX gufo: <http://purl.org/nemo/gufo#>
            PREFIX owl: <http://www.w3.org/2002/07/owl#>
            SELECT ?this WHERE {
                ?this a gufo:Role .
                FILTER NOT EXISTS { ?this a owl:Class . }
                FILTER NOT EXISTS { 
                    ?entity ?property ?this .
                    ?property rdfs:subPropertyOf* gufo:playsRole .
                }
            }
        """
    ] .

cacontology-production:ProducerRoleConflictShape rdf:type sh:NodeShape ;
    sh:targetClass cacontology-production:Producer ;
    rdfs:label "Producer Role Conflict Shape"@en ;
    rdfs:comment "Prevents conflicting roles from being assigned simultaneously."@en ;
    sh:sparql [
        sh:message "Individual cannot simultaneously be Producer and VictimRole."@en ;
        sh:prefixes [
            sh:declare [
                sh:prefix "cacontology-production" ;
                sh:namespace "https://cacontology.projectvic.org/production#"^^xsd:anyURI
            ] ,
            [
                sh:prefix "cacontology-gufo" ;
                sh:namespace "https://cacontology.projectvic.org/gufo#"^^xsd:anyURI
            ]
        ] ;
        sh:select """
            PREFIX cacontology-production: <https://cacontology.projectvic.org/production#>
            PREFIX cacontology-gufo: <https://cacontology.projectvic.org/gufo#>
            PREFIX gufo: <http://purl.org/nemo/gufo#>
            SELECT ?this WHERE {
                ?entity gufo:playsRole ?this .
                ?entity gufo:playsRole ?victimRole .
                ?this a cacontology-production:Producer .
                ?victimRole a cacontology:VictimRole .
                ?this cacontology-production:hasRoleBeginPoint ?producerBegin .
                ?victimRole cacontology-production:hasRoleBeginPoint ?victimBegin .
                FILTER(?producerBegin <= ?victimBegin)
                OPTIONAL { ?this cacontology-production:hasRoleEndPoint ?producerEnd }
                OPTIONAL { ?victimRole cacontology-production:hasRoleEndPoint ?victimEnd }
                FILTER(
                    (!BOUND(?producerEnd) && !BOUND(?victimEnd)) ||
                    (!BOUND(?producerEnd) && ?victimBegin <= ?victimEnd) ||
                    (!BOUND(?victimEnd) && ?producerBegin <= ?producerEnd) ||
                    (BOUND(?producerEnd) && BOUND(?victimEnd) && 
                     !((?producerEnd < ?victimBegin) || (?victimEnd < ?producerBegin)))
                )
            }
        """
    ] .

# =============================================================================
# gUFO EVENT-SITUATION VALIDATION SHAPES  
# =============================================================================

cacontology-production:ProductionEventShape rdf:type sh:NodeShape ;
    sh:targetClass cac-core:Event ;
    rdfs:label "Production Event Shape"@en ;
    rdfs:comment "gUFO validation for production events ensuring proper temporal modeling."@en ;
    sh:property [
        sh:path gufo:hasBeginPointInXSDDateTimeStamp ;
        sh:datatype xsd:dateTimeStamp ;
        sh:minCount 1 ;
        sh:maxCount 1 ;
        sh:message "Production event must have exactly one begin point."@en
    ] ;
    sh:property [
        sh:path gufo:hasEndPointInXSDDateTimeStamp ;
        sh:datatype xsd:dateTimeStamp ;
        sh:minCount 0 ;
        sh:maxCount 1 ;
        sh:message "Production event may have an end point."@en
    ] ;
    sh:sparql [
        sh:message "Event begin point must be before end point."@en ;
        sh:prefixes [
            sh:declare [
                sh:prefix "gufo" ;
                sh:namespace "http://purl.org/nemo/gufo#"^^xsd:anyURI
            ]
        ] ;
        sh:select """
            SELECT ?this WHERE {
                ?this gufo:hasBeginPointInXSDDateTimeStamp ?begin .
                ?this gufo:hasEndPointInXSDDateTimeStamp ?end .
                FILTER(?begin >= ?end)
            }
        """
    ] .

cacontology-production:ProductionSituationShape rdf:type sh:NodeShape ;
    sh:targetClass cac-core:Situation ;
    rdfs:label "Production Situation Shape"@en ;
    rdfs:comment "gUFO validation for production situations ensuring proper modeling of ongoing states."@en ;
    sh:sparql [
        sh:message "Situations should involve multiple entities or persist over time."@en ;
        sh:prefixes [
            sh:declare [
                sh:prefix "gufo" ;
                sh:namespace "http://purl.org/nemo/gufo#"^^xsd:anyURI
            ]
        ] ;
        sh:select """
            SELECT ?this WHERE {
                ?this a gufo:Situation .
                FILTER NOT EXISTS { 
                    { SELECT ?this WHERE { 
                        ?this gufo:involves ?entity1 .
                        ?this gufo:involves ?entity2 .
                        FILTER(?entity1 != ?entity2)
                    } }
                    UNION
                    { SELECT ?this WHERE {
                        ?this gufo:hasBeginPointInXSDDateTimeStamp ?begin .
                        ?this gufo:hasEndPointInXSDDateTimeStamp ?end .
                        FILTER(?end > ?begin)
                    } }
                }
            }
        """
    ] .

# =============================================================================
# PRODUCTION OFFENSE SHAPES
# =============================================================================

cacontology-production:ProductionOffenseShape rdf:type sh:NodeShape ;
    sh:targetClass cacontology-production:ProductionOffense ;
    rdfs:label "Production Offense Shape"@en ;
    rdfs:comment "Validation shape for CSAM production offense instances."@en ;
    sh:property [
        sh:path cacontology-production:productionMethod ;
        sh:datatype xsd:string ;
        sh:minCount 1 ;
        sh:maxCount 1 ;
        sh:in ( "direct_recording" "photography" "video_recording" "live_streaming" "photography_with_modification" "multi_session_recording" "edited_compilation" ) ;
        sh:message "Production offense must specify exactly one production method from the allowed list."@en
    ] ;
    sh:property [
        sh:path cacontology-production:sessionCount ;
        sh:datatype xsd:nonNegativeInteger ;
        sh:minCount 0 ;
        sh:maxCount 1 ;
        sh:minInclusive 1 ;
        sh:maxInclusive 1000 ;
        sh:message "Session count must be between 1 and 1000 when specified."@en
    ] ;
    sh:property [
        sh:path cacontology-production:victimCount ;
        sh:datatype xsd:nonNegativeInteger ;
        sh:minCount 1 ;
        sh:maxCount 1 ;
        sh:minInclusive 1 ;
        sh:maxInclusive 50 ;
        sh:message "Production offense must specify victim count between 1 and 50."@en
    ] ;
    sh:property [
        sh:path cacontology-production:durationMinutes ;
        sh:datatype xsd:decimal ;
        sh:minCount 0 ;
        sh:maxCount 1 ;
        sh:minInclusive 1.0 ;
        sh:maxInclusive 10080.0 ;
        sh:message "Duration must be between 1 minute and 1 week (10080 minutes)."@en
    ] ;
    sh:property [
        sh:path uco-core:startTime ;
        sh:datatype xsd:dateTime ;
        sh:minCount 0 ;
        sh:maxCount 1 ;
        sh:message "Production offense may have a start time."@en
    ] ;
    sh:property [
        sh:path uco-core:endTime ;
        sh:datatype xsd:dateTime ;
        sh:minCount 0 ;
        sh:maxCount 1 ;
        sh:message "Production offense may have an end time."@en
    ] .

cacontology-production:LiveProductionEventShape rdf:type sh:NodeShape ;
    sh:targetClass cacontology-production:LiveProductionEvent ;
    rdfs:label "Live Production Event Shape"@en ;
    rdfs:comment "Validation shape for live production event instances."@en ;
    sh:property [
        sh:path cacontology-production:streamingPlatform ;
        sh:datatype xsd:string ;
        sh:minCount 1 ;
        sh:maxCount 1 ;
        sh:minLength 2 ;
        sh:maxLength 100 ;
        sh:message "Live production event must specify streaming platform (2-100 characters)."@en
    ] ;
    sh:property [
        sh:path cacontology-production:viewerCount ;
        sh:datatype xsd:nonNegativeInteger ;
        sh:minCount 0 ;
        sh:maxCount 1 ;
        sh:minInclusive 1 ;
        sh:maxInclusive 10000 ;
        sh:message "Viewer count must be between 1 and 10000 when specified."@en
    ] .

cacontology-production:ExtendedProductionOperationShape rdf:type sh:NodeShape ;
    sh:targetClass cacontology-production:ExtendedProductionOperation ;
    rdfs:label "Extended Production Operation Shape"@en ;
    rdfs:comment "Validation shape for extended production operation instances."@en ;
    sh:property [
        sh:path cacontology-production:operationDuration ;
        sh:datatype xsd:decimal ;
        sh:minCount 1 ;
        sh:maxCount 1 ;
        sh:minInclusive 7.0 ;
        sh:maxInclusive 3650.0 ;
        sh:message "Extended operation duration must be between 7 days and 10 years."@en
    ] ;
    sh:property [
        sh:path cacontology-production:totalSessions ;
        sh:datatype xsd:nonNegativeInteger ;
        sh:minCount 1 ;
        sh:maxCount 1 ;
        sh:minInclusive 5 ;
        sh:maxInclusive 5000 ;
        sh:message "Extended operation must have between 5 and 5000 total sessions."@en
    ] .

# =============================================================================
# PRODUCER ROLE SHAPES
# =============================================================================

cacontology-production:ProducerShape rdf:type sh:NodeShape ;
    sh:targetClass cacontology-production:Producer ;
    rdfs:label "Producer Shape"@en ;
    rdfs:comment "Validation shape for producer role instances."@en ;
    sh:property [
        sh:path cacontology-production:productionExperience ;
        sh:datatype xsd:decimal ;
        sh:minCount 0 ;
        sh:maxCount 1 ;
        sh:minInclusive 0.0 ;
        sh:maxInclusive 50.0 ;
        sh:message "Production experience must be between 0 and 50 years."@en
    ] ;
    sh:property [
        sh:path cacontology-production:technicalSkillLevel ;
        sh:datatype xsd:string ;
        sh:minCount 0 ;
        sh:maxCount 1 ;
        sh:in ( "novice" "intermediate" "advanced" "expert" "professional" ) ;
        sh:message "Technical skill level must be from the allowed list."@en
    ] .

cacontology-production:PrimaryProducerShape rdf:type sh:NodeShape ;
    sh:targetClass cacontology-production:PrimaryProducer ;
    rdfs:label "Primary Producer Shape"@en ;
    rdfs:comment "Validation shape for primary producer instances."@en ;
    sh:property [
        sh:path cacontology-production:leadershipRole ;
        sh:datatype xsd:boolean ;
        sh:minCount 1 ;
        sh:maxCount 1 ;
        sh:hasValue true ;
        sh:message "Primary producer must have leadership role set to true."@en
    ] .

cacontology-production:FacilitatorShape rdf:type sh:NodeShape ;
    sh:targetClass cacontology-production:Facilitator ;
    rdfs:label "Facilitator Shape"@en ;
    rdfs:comment "Validation shape for facilitator role instances."@en ;
    sh:property [
        sh:path cacontology-production:facilitationType ;
        sh:datatype xsd:string ;
        sh:minCount 1 ;
        sh:maxCount 1 ;
        sh:in ( "equipment_provider" "location_provider" "victim_recruiter" "technical_support" "distribution_coordinator" "financial_facilitator" ) ;
        sh:message "Facilitator must specify facilitation type from the allowed list."@en
    ] .

# =============================================================================
# EQUIPMENT AND TECHNICAL SHAPES
# =============================================================================

cacontology-production:ProductionEquipmentShape rdf:type sh:NodeShape ;
    sh:targetClass cacontology-production:ProductionEquipment ;
    rdfs:label "Production Equipment Shape"@en ;
    rdfs:comment "Validation shape for production equipment instances."@en ;
    sh:property [
        sh:path cacontology-production:equipmentType ;
        sh:datatype xsd:string ;
        sh:minCount 1 ;
        sh:maxCount 1 ;
        sh:in ( "camera" "smartphone" "tablet" "laptop" "desktop" "recording_device" "lighting_equipment" "audio_equipment" "editing_software" "streaming_equipment" ) ;
        sh:message "Equipment must specify type from the allowed list."@en
    ] ;
    sh:property [
        sh:path cacontology-production:equipmentCondition ;
        sh:datatype xsd:string ;
        sh:minCount 0 ;
        sh:maxCount 1 ;
        sh:in ( "new" "good" "fair" "poor" "damaged" "modified" ) ;
        sh:message "Equipment condition must be from the allowed list."@en
    ] .

cacontology-production:RecordingDeviceShape rdf:type sh:NodeShape ;
    sh:targetClass cacontology-production:RecordingDevice ;
    rdfs:label "Recording Device Shape"@en ;
    rdfs:comment "Validation shape for recording device instances."@en ;
    sh:property [
        sh:path cacontology-production:recordingQuality ;
        sh:datatype xsd:string ;
        sh:minCount 0 ;
        sh:maxCount 1 ;
        sh:in ( "low" "standard" "high" "ultra_high" "professional" ) ;
        sh:message "Recording quality must be from the allowed list."@en
    ] ;
    sh:property [
        sh:path cacontology-production:storageCapacity ;
        sh:datatype xsd:decimal ;
        sh:minCount 0 ;
        sh:maxCount 1 ;
        sh:minInclusive 0.1 ;
        sh:maxInclusive 100000.0 ;
        sh:message "Storage capacity must be between 0.1 GB and 100 TB."@en
    ] .

# =============================================================================
# LOCATION AND ENVIRONMENT SHAPES
# =============================================================================

cacontology-production:ProductionLocationShape rdf:type sh:NodeShape ;
    sh:targetClass cacontology-production:ProductionLocation ;
    rdfs:label "Production Location Shape"@en ;
    rdfs:comment "Validation shape for production location instances."@en ;
    sh:property [
        sh:path cacontology-production:locationType ;
        sh:datatype xsd:string ;
        sh:minCount 1 ;
        sh:maxCount 1 ;
        sh:in ( "residential" "commercial" "institutional" "outdoor" "vehicle" "temporary" "mobile" ) ;
        sh:message "Production location must specify type from the allowed list."@en
    ] ;
    sh:property [
        sh:path cacontology-production:privacyLevel ;
        sh:datatype xsd:string ;
        sh:minCount 1 ;
        sh:maxCount 1 ;
        sh:in ( "public" "semi_private" "private" "highly_private" "isolated" ) ;
        sh:message "Production location must specify privacy level from the allowed list."@en
    ] ;
    sh:property [
        sh:path cacontology-production:accessControl ;
        sh:datatype xsd:string ;
        sh:minCount 0 ;
        sh:maxCount 1 ;
        sh:in ( "open" "restricted" "controlled" "secured" "locked" ) ;
        sh:message "Access control must be from the allowed list."@en
    ] .

# =============================================================================
# IMAGE POST-PROCESSING SHAPES
# =============================================================================

cacontology-production:ImagePostProcessingShape rdf:type sh:NodeShape ;
    sh:targetClass cacontology-production:ImagePostProcessing ;
    rdfs:label "Image Post-Processing Shape"@en ;
    rdfs:comment "Validation shape for image post-processing instances."@en ;
    sh:property [
        sh:path cacontology-production:modificationCount ;
        sh:datatype xsd:nonNegativeInteger ;
        sh:minCount 1 ;
        sh:maxCount 1 ;
        sh:minInclusive 1 ;
        sh:maxInclusive 1000 ;
        sh:message "Image post-processing must specify modification count between 1 and 1000."@en
    ] ;
    sh:property [
        sh:path cacontology-production:modificationSoftware ;
        sh:datatype xsd:string ;
        sh:minCount 1 ;
        sh:maxCount 1 ;
        sh:minLength 2 ;
        sh:maxLength 100 ;
        sh:message "Modification software must be specified (2-100 characters)."@en
    ] .

cacontology-production:TextOverlayShape rdf:type sh:NodeShape ;
    sh:targetClass cacontology-production:TextOverlay ;
    rdfs:label "Text Overlay Shape"@en ;
    rdfs:comment "Validation shape for text overlay instances."@en ;
    sh:property [
        sh:path cacontology-production:textType ;
        sh:datatype xsd:string ;
        sh:minCount 1 ;
        sh:maxCount 1 ;
        sh:in ( "victim_name" "victim_name_and_slang" "explicit_text" "identifying_text" "threatening_text" "instructional_text" ) ;
        sh:message "Text overlay must specify text type from the allowed list."@en
    ] ;
    sh:property [
        sh:path cacontology-production:textPlacement ;
        sh:datatype xsd:string ;
        sh:minCount 1 ;
        sh:maxCount 1 ;
        sh:in ( "overlay_on_image" "caption_below" "watermark" "corner_placement" "center_placement" ) ;
        sh:message "Text overlay must specify placement from the allowed list."@en
    ] .

# =============================================================================
# OBJECT PROPERTY SHAPES
# =============================================================================

cacontology-production:ProducesContentShape rdf:type sh:PropertyShape ;
    sh:path cacontology-production:producesContent ;
    sh:name "produces content" ;
    sh:description "Links producer to content they create" ;
    sh:class uco-core:UcoObject ;
    sh:minCount 0 .

cacontology-production:UsesEquipmentShape rdf:type sh:PropertyShape ;
    sh:path cacontology-production:usesEquipment ;
    sh:name "uses equipment" ;
    sh:description "Links production to equipment used" ;
    sh:class cacontology-production:ProductionEquipment ;
    sh:minCount 0 .

cacontology-production:ProducedAtShape rdf:type sh:PropertyShape ;
    sh:path cacontology-production:producedAt ;
    sh:name "produced at" ;
    sh:description "Links production to location where it occurred" ;
    sh:class uco-location:Location ;
    sh:minCount 0 .

cacontology-production:FacilitatesProductionShape rdf:type sh:PropertyShape ;
    sh:path cacontology-production:facilitatesProduction ;
    sh:name "facilitates production" ;
    sh:description "Links facilitator to production they assist" ;
    sh:class cacontology-production:ProductionOffense ;
    sh:minCount 0 .

cacontology-production:ModifiesImagesShape rdf:type sh:PropertyShape ;
    sh:path cacontology-production:modifiesImages ;
    sh:name "modifies images" ;
    sh:description "Links post-processing to image modification" ;
    sh:class uco-core:UcoObject ;
    sh:minCount 0 .

cacontology-production:OverlaysTextShape rdf:type sh:PropertyShape ;
    sh:path cacontology-production:overlaysText ;
    sh:name "overlays text" ;
    sh:description "Links text overlay to image modification" ;
    sh:class cacontology-production:ImagePostProcessing ;
    sh:minCount 0 .

# =============================================================================
# CROSS-REFERENCE VALIDATION SHAPES
# =============================================================================

cacontology-production:ProductionCrossReferenceShape rdf:type sh:NodeShape ;
    sh:targetClass cacontology-production:ProductionOffense ;
    rdfs:label "Production Cross Reference Shape"@en ;
    rdfs:comment "Validates cross-references between production and related entities."@en ;
    sh:sparql [
        sh:message "Production offense should have at least one producer or facilitator."@en ;
        sh:select """
            SELECT $this
            WHERE {
                $this a cacontology-production:ProductionOffense .
                FILTER NOT EXISTS {
                    { ?producer cacontology-production:producesContent $this } UNION
                    { ?facilitator cacontology-production:facilitatesProduction $this }
                }
            }
        """
    ] .

cacontology-production:EquipmentUsageValidationShape rdf:type sh:NodeShape ;
    sh:targetClass cacontology-production:ProductionOffense ;
    rdfs:label "Equipment Usage Validation Shape"@en ;
    rdfs:comment "Validates that production offenses have appropriate equipment."@en ;
    sh:sparql [
        sh:message "Production offense should specify equipment used for recording or streaming."@en ;
        sh:select """
            SELECT $this
            WHERE {
                $this a cacontology-production:ProductionOffense ;
                      cacontology-production:productionMethod ?method .
                FILTER (?method IN ("direct_recording", "video_recording", "live_streaming"))
                FILTER NOT EXISTS {
                    $this cacontology-production:usesEquipment ?equipment .
                    ?equipment a cacontology-production:RecordingDevice .
                }
            }
        """
    ] .

# =============================================================================
# TEMPORAL VALIDATION SHAPES
# =============================================================================

cacontology-production:TemporalValidationShape rdf:type sh:NodeShape ;
    sh:targetClass cacontology-production:ProductionOffense ;
    rdfs:label "Temporal Validation Shape"@en ;
    rdfs:comment "Validates temporal consistency in production offenses."@en ;
    sh:sparql [
        sh:message "Start time must be before end time when both are specified."@en ;
        sh:select """
            SELECT $this
            WHERE {
                $this uco-core:startTime ?start ;
                      uco-core:endTime ?end .
                FILTER (?start >= ?end)
            }
        """
    ] .

cacontology-production:ExtendedOperationValidationShape rdf:type sh:NodeShape ;
    sh:targetClass cacontology-production:ExtendedProductionOperation ;
    rdfs:label "Extended Operation Validation Shape"@en ;
    rdfs:comment "Validates extended production operation consistency."@en ;
    sh:sparql [
        sh:message "Extended operation duration should be consistent with total sessions."@en ;
        sh:select """
            SELECT $this
            WHERE {
                $this cacontology-production:operationDuration ?duration ;
                      cacontology-production:totalSessions ?sessions .
                FILTER (?sessions > (?duration * 10))
            }
        """
    ] .

# =============================================================================
# DATA QUALITY SHAPES
# =============================================================================

cacontology-production:DataQualityShape rdf:type sh:NodeShape ;
    sh:targetClass cacontology-production:ProductionOffense ;
    rdfs:label "Data Quality Shape"@en ;
    rdfs:comment "Validates data quality for production offenses."@en ;
    sh:property [
        sh:path rdfs:label ;
        sh:datatype xsd:string ;
        sh:minCount 0 ;
        sh:maxCount 1 ;
        sh:minLength 5 ;
        sh:maxLength 200 ;
        sh:message "Label should be between 5 and 200 characters when provided."@en
    ] ;
    sh:property [
        sh:path rdfs:comment ;
        sh:datatype xsd:string ;
        sh:minCount 0 ;
        sh:maxCount 1 ;
        sh:minLength 10 ;
        sh:maxLength 1000 ;
        sh:message "Comment should be between 10 and 1000 characters when provided."@en
    ] . 