copybook-core 0.4.3

Core COBOL copybook parser, schema, and validation primitives.
Documentation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
// SPDX-License-Identifier: AGPL-3.0-or-later
//! Audit Event System
//!
//! Defines the core audit event structure and payload types for comprehensive
//! enterprise audit trail generation and validation.

use serde::{Deserialize, Serialize};
use std::collections::HashMap;

use super::{AuditContext, generate_audit_id, generate_integrity_hash};

/// Core audit event structure
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct AuditEvent {
    /// Unique audit event identifier
    pub event_id: String,

    /// Event timestamp (ISO 8601 with nanosecond precision)
    pub timestamp: String,

    /// Event type classification
    pub event_type: AuditEventType,

    /// Operation context information
    pub context: AuditContext,

    /// Audit event payload data
    pub payload: AuditPayload,

    /// Cryptographic integrity hash
    pub integrity_hash: String,

    /// Previous event hash for chain integrity
    pub previous_hash: Option<String>,

    /// Event severity level
    pub severity: AuditSeverity,

    /// Event source component
    pub source: String,

    /// Event version for schema evolution
    pub event_version: String,
}

impl AuditEvent {
    /// Create a new audit event
    pub fn new(event_type: AuditEventType, context: AuditContext, payload: AuditPayload) -> Self {
        let event_id = generate_audit_id();
        let timestamp = chrono::Utc::now().to_rfc3339_opts(chrono::SecondsFormat::Nanos, true);
        let severity = payload.default_severity();
        let source = Self::determine_source(event_type);

        let mut event = Self {
            event_id,
            timestamp,
            event_type,
            context,
            payload,
            integrity_hash: String::new(), // Will be set below
            previous_hash: None,           // Will be set by audit logger
            severity,
            source,
            event_version: "1.0.0".to_string(),
        };

        // Generate integrity hash (exclude hash field from calculation)
        let mut event_for_hash = event.clone();
        event_for_hash.integrity_hash = String::new();
        let event_bytes = match serde_json::to_vec(&event_for_hash) {
            Ok(bytes) => bytes,
            Err(e) => {
                // Fallback to a minimal serializable representation on serialization failure
                let fallback_data = format!(
                    "{{\"event_id\":\"{}\",\"timestamp\":\"{}\",\"event_type\":\"{:?}\",\"serialization_error\":\"{}\"}}",
                    event.event_id, event.timestamp, event.event_type, e
                );
                fallback_data.into_bytes()
            }
        };
        event.integrity_hash = generate_integrity_hash(&event_bytes, None);

        event
    }

    /// Create event with specific severity
    #[must_use]
    pub fn with_severity(mut self, severity: AuditSeverity) -> Self {
        self.severity = severity;

        // Regenerate integrity hash with updated severity (exclude hash field from calculation)
        let mut event_for_hash = self.clone();
        event_for_hash.integrity_hash = String::new();
        let event_bytes = match serde_json::to_vec(&event_for_hash) {
            Ok(bytes) => bytes,
            Err(e) => {
                // Fallback to a minimal serializable representation on serialization failure
                let fallback_data = format!(
                    "{{\"event_id\":\"{}\",\"timestamp\":\"{}\",\"event_type\":\"{:?}\",\"severity\":\"{:?}\",\"serialization_error\":\"{}\"}}",
                    self.event_id, self.timestamp, self.event_type, self.severity, e
                );
                fallback_data.into_bytes()
            }
        };
        self.integrity_hash = generate_integrity_hash(&event_bytes, None);

        self
    }

    /// Set the previous event hash for chain integrity
    #[must_use]
    pub fn with_previous_hash(mut self, previous_hash: String) -> Self {
        self.previous_hash = Some(previous_hash);

        // Regenerate integrity hash with previous hash (exclude hash field from calculation)
        let mut event_for_hash = self.clone();
        event_for_hash.integrity_hash = String::new();
        event_for_hash.previous_hash = None; // Also exclude previous_hash from serialization
        let event_bytes = match serde_json::to_vec(&event_for_hash) {
            Ok(bytes) => bytes,
            Err(e) => {
                // Fallback to a minimal serializable representation on serialization failure
                let fallback_data = format!(
                    "{{\"event_id\":\"{}\",\"timestamp\":\"{}\",\"event_type\":\"{:?}\",\"serialization_error\":\"{}\"}}",
                    self.event_id, self.timestamp, self.event_type, e
                );
                fallback_data.into_bytes()
            }
        };
        self.integrity_hash = generate_integrity_hash(&event_bytes, self.previous_hash.as_deref());

        self
    }

    /// Determine the source component based on event type
    fn determine_source(event_type: AuditEventType) -> String {
        match event_type {
            AuditEventType::CopybookParse => "copybook-core::parser",
            AuditEventType::DataValidation => "copybook-codec::validator",
            AuditEventType::DataTransformation => "copybook-codec::transformer",
            AuditEventType::PerformanceMeasurement => "copybook-bench::performance",
            AuditEventType::ComplianceCheck => "copybook-core::compliance",
            AuditEventType::SecurityEvent => "copybook-core::security",
            AuditEventType::LineageTracking => "copybook-core::lineage",
            AuditEventType::ErrorEvent => "copybook-core::error",
            AuditEventType::AccessEvent => "copybook-core::access",
            AuditEventType::ConfigurationChange => "copybook-core::config",
        }
        .to_string()
    }

    /// Check if this event requires immediate attention
    pub fn requires_immediate_attention(&self) -> bool {
        matches!(self.severity, AuditSeverity::High | AuditSeverity::Critical)
    }

    /// Get event correlation ID from context
    pub fn correlation_id(&self) -> &str {
        &self.context.operation_id
    }
}

/// Audit event type classification
#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
pub enum AuditEventType {
    /// Copybook parsing operations
    CopybookParse,
    /// Data validation and verification
    DataValidation,
    /// Data transformation (decode/encode)
    DataTransformation,
    /// Performance measurement events
    PerformanceMeasurement,
    /// Compliance validation events
    ComplianceCheck,
    /// Security-relevant events
    SecurityEvent,
    /// Data lineage tracking
    LineageTracking,
    /// Error and exception events
    ErrorEvent,
    /// Access control events
    AccessEvent,
    /// Configuration change events
    ConfigurationChange,
}

/// Audit event severity levels
#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq, PartialOrd, Ord)]
pub enum AuditSeverity {
    /// Informational event with no action required
    Info,
    /// Low-severity event requiring awareness
    Low,
    /// Medium-severity event requiring investigation
    Medium,
    /// High-severity event requiring prompt attention
    High,
    /// Critical event requiring immediate response
    Critical,
}

impl std::fmt::Display for AuditEventType {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        match self {
            Self::CopybookParse => f.write_str("CopybookParse"),
            Self::DataValidation => f.write_str("DataValidation"),
            Self::DataTransformation => f.write_str("DataTransformation"),
            Self::PerformanceMeasurement => f.write_str("PerformanceMeasurement"),
            Self::ComplianceCheck => f.write_str("ComplianceCheck"),
            Self::SecurityEvent => f.write_str("SecurityEvent"),
            Self::LineageTracking => f.write_str("LineageTracking"),
            Self::ErrorEvent => f.write_str("ErrorEvent"),
            Self::AccessEvent => f.write_str("AccessEvent"),
            Self::ConfigurationChange => f.write_str("ConfigurationChange"),
        }
    }
}

impl std::fmt::Display for AuditSeverity {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        match self {
            Self::Info => f.write_str("Info"),
            Self::Low => f.write_str("Low"),
            Self::Medium => f.write_str("Medium"),
            Self::High => f.write_str("High"),
            Self::Critical => f.write_str("Critical"),
        }
    }
}

impl AuditSeverity {
    /// Return the CEF-spec numeric severity (0-10 scale).
    #[must_use]
    pub fn cef_numeric(self) -> u8 {
        match self {
            Self::Info => 1,
            Self::Low => 3,
            Self::Medium => 5,
            Self::High => 7,
            Self::Critical => 10,
        }
    }
}

/// Audit event payload containing event-specific data
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(tag = "type", content = "data")]
pub enum AuditPayload {
    /// Copybook parsing operation payload
    CopybookParse {
        /// File path of the parsed copybook
        copybook_path: String,
        /// SHA-based fingerprint of the parsed schema
        schema_fingerprint: String,
        /// Outcome of the parse operation
        parse_result: ParseResult,
        /// Wall-clock parsing duration in milliseconds
        parsing_duration_ms: u64,
        /// Total number of fields parsed
        field_count: usize,
        /// Number of Level-88 condition fields parsed
        level_88_count: usize,
        /// Number of errors encountered during parsing
        error_count: usize,
        /// Non-fatal warning messages emitted during parsing
        warnings: Vec<String>,
    },

    /// Data validation operation payload
    DataValidation {
        /// Path of the input file being validated
        input_file: String,
        /// Outcome of the validation operation
        validation_result: ValidationResult,
        /// Wall-clock validation duration in milliseconds
        validation_duration_ms: u64,
        /// Total number of records validated
        records_validated: u64,
        /// Number of validation errors found
        errors_found: u64,
        /// Detailed list of validation errors
        error_details: Vec<ValidationError>,
        /// Names of the validation rules applied
        validation_rules: Vec<String>,
    },

    /// Data transformation (decode/encode) operation payload
    DataTransformation {
        /// Type of transformation operation performed
        operation: TransformationOperation,
        /// Path of the input file
        input_file: String,
        /// Path of the output file
        output_file: String,
        /// Outcome of the transformation operation
        transformation_result: TransformationResult,
        /// Wall-clock processing duration in milliseconds
        processing_duration_ms: u64,
        /// Total number of records processed
        records_processed: u64,
        /// Total number of bytes processed
        bytes_processed: u64,
        /// Measured throughput in bytes per second
        throughput_bytes_per_sec: u64,
        /// Peak memory usage in megabytes
        memory_usage_mb: u64,
    },

    /// Performance measurement event payload
    PerformanceMeasurement {
        /// Category of the performance measurement
        measurement_type: PerformanceMeasurementType,
        /// Identifier of the baseline used for comparison
        baseline_id: Option<String>,
        /// Collected performance metrics
        metrics: PerformanceMetrics,
        /// Result of comparing metrics against the baseline
        comparison_result: Option<ComparisonResult>,
        /// Whether a performance regression was detected
        regression_detected: bool,
    },

    /// Compliance check operation payload
    ComplianceCheck {
        /// Name of the compliance framework evaluated
        compliance_framework: String,
        /// Outcome of the compliance validation
        validation_result: ComplianceValidationResult,
        /// Detailed list of compliance violations found
        violations: Vec<ComplianceViolationDetail>,
        /// Whether remediation actions are required
        remediation_required: bool,
        /// Scheduled date for the next compliance review
        next_review_date: Option<String>,
    },

    /// Security-relevant event payload
    SecurityEvent {
        /// Classification of the security event
        security_event_type: SecurityEventType,
        /// Severity level of the security event
        severity: String,
        /// Resources affected by the security event
        affected_resources: Vec<String>,
        /// Indicators of the detected threat
        threat_indicators: Vec<String>,
        /// Recommended remediation actions
        remediation_actions: Vec<String>,
        /// Associated incident tracking identifier
        incident_id: Option<String>,
    },

    /// Data lineage tracking payload
    LineageTracking {
        /// Originating system of the data
        source_system: String,
        /// Destination system for the data
        target_system: String,
        /// Field-level source-to-target mappings
        field_mappings: Vec<FieldMapping>,
        /// Transformation rules applied during lineage
        transformation_rules: Vec<TransformationRule>,
        /// Data quality score (0.0 to 1.0)
        quality_score: f64,
        /// Summary of downstream impact assessment
        impact_assessment: Option<ImpactAssessmentSummary>,
    },

    /// Error and exception event payload
    ErrorEvent {
        /// Structured error code identifier
        error_code: String,
        /// Human-readable error description
        error_message: String,
        /// Category grouping for the error
        error_category: String,
        /// Optional stack trace for debugging
        stack_trace: Option<String>,
        /// Additional key-value context for the error
        context_information: HashMap<String, String>,
        /// Suggested recovery actions
        recovery_actions: Vec<String>,
        /// Assessed user impact level
        user_impact: UserImpactLevel,
    },

    /// Access control event payload
    AccessEvent {
        /// Type of access attempted
        access_type: AccessType,
        /// Kind of resource being accessed
        resource_type: String,
        /// Identifier of the accessed resource
        resource_id: String,
        /// Outcome of the access attempt
        access_result: AccessResult,
        /// Identifier of the user performing the access
        user_id: String,
        /// IP address of the access origin
        source_ip: Option<String>,
        /// User agent string of the client
        user_agent: Option<String>,
        /// Session identifier for the access
        session_id: Option<String>,
    },

    /// Configuration change event payload
    ConfigurationChange {
        /// Component whose configuration changed
        component: String,
        /// Type of configuration change performed
        change_type: ConfigurationChangeType,
        /// Previous configuration value before the change
        old_configuration: Option<String>,
        /// New configuration value after the change
        new_configuration: String,
        /// Reason or justification for the change
        change_reason: String,
        /// Identifier of the approver, if applicable
        approved_by: Option<String>,
        /// Whether the change can be rolled back
        rollback_available: bool,
    },
}

impl AuditPayload {
    /// Get the default severity for this payload type
    pub fn default_severity(&self) -> AuditSeverity {
        match self {
            AuditPayload::CopybookParse { parse_result, .. } => match parse_result {
                ParseResult::Success => AuditSeverity::Info,
                ParseResult::SuccessWithWarnings => AuditSeverity::Low,
                ParseResult::Failed => AuditSeverity::High,
            },
            AuditPayload::DataValidation {
                validation_result, ..
            } => match validation_result {
                ValidationResult::Valid => AuditSeverity::Info,
                ValidationResult::ValidWithWarnings => AuditSeverity::Low,
                ValidationResult::Invalid => AuditSeverity::Medium,
            },
            AuditPayload::DataTransformation {
                transformation_result,
                ..
            } => match transformation_result {
                TransformationResult::Success => AuditSeverity::Info,
                TransformationResult::PartialSuccess => AuditSeverity::Medium,
                TransformationResult::Failed => AuditSeverity::High,
            },
            AuditPayload::PerformanceMeasurement {
                regression_detected,
                ..
            } => {
                if *regression_detected {
                    AuditSeverity::Medium
                } else {
                    AuditSeverity::Info
                }
            }
            AuditPayload::ComplianceCheck {
                remediation_required,
                ..
            } => {
                if *remediation_required {
                    AuditSeverity::High
                } else {
                    AuditSeverity::Info
                }
            }
            AuditPayload::SecurityEvent { .. } => AuditSeverity::High,
            AuditPayload::LineageTracking { .. } => AuditSeverity::Info,
            AuditPayload::ErrorEvent { user_impact, .. } => match user_impact {
                UserImpactLevel::None => AuditSeverity::Low,
                UserImpactLevel::Low => AuditSeverity::Medium,
                UserImpactLevel::Medium => AuditSeverity::High,
                UserImpactLevel::High => AuditSeverity::Critical,
            },
            AuditPayload::AccessEvent { access_result, .. } => match access_result {
                AccessResult::Success => AuditSeverity::Info,
                AccessResult::Denied => AuditSeverity::Medium,
                AccessResult::Failed => AuditSeverity::High,
            },
            AuditPayload::ConfigurationChange { .. } => AuditSeverity::Medium,
        }
    }
}

// Supporting data structures for audit payloads

/// Outcome of a copybook parse operation
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub enum ParseResult {
    /// Parse completed successfully with no issues
    Success,
    /// Parse completed with non-fatal warnings
    SuccessWithWarnings,
    /// Parse failed with errors
    Failed,
}

/// Outcome of a data validation operation
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub enum ValidationResult {
    /// Data is fully valid
    Valid,
    /// Data is valid but has non-fatal warnings
    ValidWithWarnings,
    /// Data is invalid
    Invalid,
}

/// Details of a single validation error
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ValidationError {
    /// Structured error code identifier
    pub error_code: String,
    /// Dot-separated path to the field with the error
    pub field_path: Option<String>,
    /// Zero-based index of the record containing the error
    pub record_index: Option<u64>,
    /// Byte offset within the record where the error occurred
    pub byte_offset: Option<u64>,
    /// Human-readable error description
    pub message: String,
}

/// Type of data transformation operation
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub enum TransformationOperation {
    /// Binary-to-JSON decode operation
    Decode,
    /// JSON-to-binary encode operation
    Encode,
    /// Data validation operation
    Validate,
    /// Format conversion operation
    Convert,
}

/// Outcome of a data transformation operation
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub enum TransformationResult {
    /// Transformation completed successfully
    Success,
    /// Transformation completed with some records failing
    PartialSuccess,
    /// Transformation failed entirely
    Failed,
}

/// Category of performance measurement
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub enum PerformanceMeasurementType {
    /// Throughput measurement in bytes per second
    Throughput,
    /// Latency measurement in milliseconds
    Latency,
    /// CPU and memory resource utilization measurement
    ResourceUtilization,
    /// Baseline establishment measurement
    Baseline,
}

/// Collected performance metrics for a measurement event
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct PerformanceMetrics {
    /// Measured throughput in bytes per second
    pub throughput_bytes_per_sec: u64,
    /// Measured latency in milliseconds
    pub latency_ms: u64,
    /// CPU usage as a percentage (0.0 to 100.0)
    pub cpu_usage_percent: f64,
    /// Memory usage in megabytes
    pub memory_usage_mb: u64,
    /// Total number of I/O operations performed
    pub io_operations: u64,
}

/// Result of comparing metrics against a performance baseline
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub enum ComparisonResult {
    /// Metrics exceed the baseline (improvement)
    BetterThanBaseline,
    /// Metrics are within acceptable baseline tolerance
    WithinBaseline,
    /// Metrics are below the baseline (minor regression)
    BelowBaseline,
    /// Metrics show a significant regression beyond tolerance
    SignificantRegression,
}

/// Outcome of a compliance validation check
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub enum ComplianceValidationResult {
    /// Fully compliant with the framework requirements
    Compliant,
    /// Non-compliant with one or more requirements
    NonCompliant,
    /// Requires manual review to determine compliance
    RequiresReview,
}

/// Details of a single compliance violation
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ComplianceViolationDetail {
    /// Unique identifier for the violation
    pub violation_id: String,
    /// Regulation or standard that was violated
    pub regulation: String,
    /// Severity level of the violation
    pub severity: String,
    /// Human-readable description of the violation
    pub description: String,
    /// Recommended remediation steps
    pub remediation: String,
}

/// Classification of a security event
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub enum SecurityEventType {
    /// Access attempt without valid credentials
    UnauthorizedAccess,
    /// Failed authentication attempt
    AuthenticationFailure,
    /// Denied authorization for a requested operation
    AuthorizationFailure,
    /// Detected or confirmed data breach
    DataBreach,
    /// Data or system integrity violation detected
    IntegrityViolation,
    /// Unauthorized configuration modification detected
    ConfigurationTampering,
    /// Activity matching suspicious behavior patterns
    SuspiciousActivity,
}

/// Mapping between source and target fields in data lineage
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct FieldMapping {
    /// Name of the source field
    pub source_field: String,
    /// Name of the target field
    pub target_field: String,
    /// Description of the transformation applied
    pub transformation: String,
    /// Confidence score for the mapping (0.0 to 1.0)
    pub confidence_score: f64,
}

/// Rule applied during a data transformation
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct TransformationRule {
    /// Unique identifier for the rule
    pub rule_id: String,
    /// Category or type of the rule
    pub rule_type: String,
    /// Human-readable description of the rule
    pub description: String,
    /// Key-value parameters for the rule
    pub parameters: HashMap<String, String>,
}

/// Summary of a downstream impact assessment
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ImpactAssessmentSummary {
    /// Number of downstream systems affected
    pub affected_systems: u32,
    /// Overall risk level of the impact
    pub risk_level: String,
    /// Description of the estimated impact
    pub estimated_impact: String,
}

/// Level of impact on end users
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub enum UserImpactLevel {
    /// No user impact
    None,
    /// Minor user impact with workaround available
    Low,
    /// Moderate user impact affecting some workflows
    Medium,
    /// Severe user impact blocking critical workflows
    High,
}

/// Type of resource access attempted
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub enum AccessType {
    /// Read access to a resource
    Read,
    /// Write or modify access to a resource
    Write,
    /// Execute or invoke access to a resource
    Execute,
    /// Delete access to a resource
    Delete,
    /// Administrative access to a resource
    Admin,
}

/// Outcome of a resource access attempt
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub enum AccessResult {
    /// Access was granted successfully
    Success,
    /// Access was denied by policy
    Denied,
    /// Access failed due to an error
    Failed,
}

/// Type of configuration change performed
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub enum ConfigurationChangeType {
    /// New configuration created
    Create,
    /// Existing configuration updated
    Update,
    /// Configuration deleted
    Delete,
    /// Configuration imported from external source
    Import,
    /// Configuration exported to external destination
    Export,
}

#[cfg(test)]
#[allow(clippy::expect_used)]
#[allow(clippy::unwrap_used)]
mod tests {
    use super::*;
    use crate::audit::AuditContext;

    #[test]
    fn test_audit_event_creation() {
        let context = AuditContext::new();
        let payload = AuditPayload::CopybookParse {
            copybook_path: "test.cpy".to_string(),
            schema_fingerprint: "abc123".to_string(),
            parse_result: ParseResult::Success,
            parsing_duration_ms: 100,
            field_count: 10,
            level_88_count: 2,
            error_count: 0,
            warnings: vec![],
        };

        let event = AuditEvent::new(AuditEventType::CopybookParse, context, payload);

        assert!(event.event_id.starts_with("audit-"));
        assert!(!event.timestamp.is_empty());
        assert_eq!(event.event_type, AuditEventType::CopybookParse);
        assert_eq!(event.severity, AuditSeverity::Info);
        assert!(!event.integrity_hash.is_empty());
    }

    #[test]
    fn test_event_severity_override() {
        let context = AuditContext::new();
        let payload = AuditPayload::ErrorEvent {
            error_code: "TEST001".to_string(),
            error_message: "Test error".to_string(),
            error_category: "test".to_string(),
            stack_trace: None,
            context_information: HashMap::new(),
            recovery_actions: vec![],
            user_impact: UserImpactLevel::None,
        };

        let event = AuditEvent::new(AuditEventType::ErrorEvent, context, payload)
            .with_severity(AuditSeverity::Critical);

        assert_eq!(event.severity, AuditSeverity::Critical);
    }

    #[test]
    fn test_payload_default_severity() {
        let success_payload = AuditPayload::CopybookParse {
            copybook_path: "test.cpy".to_string(),
            schema_fingerprint: "abc123".to_string(),
            parse_result: ParseResult::Success,
            parsing_duration_ms: 100,
            field_count: 10,
            level_88_count: 2,
            error_count: 0,
            warnings: vec![],
        };

        assert_eq!(success_payload.default_severity(), AuditSeverity::Info);

        let failed_payload = AuditPayload::CopybookParse {
            copybook_path: "test.cpy".to_string(),
            schema_fingerprint: "abc123".to_string(),
            parse_result: ParseResult::Failed,
            parsing_duration_ms: 100,
            field_count: 0,
            level_88_count: 0,
            error_count: 5,
            warnings: vec![],
        };

        assert_eq!(failed_payload.default_severity(), AuditSeverity::High);
    }

    #[test]
    fn test_event_requires_immediate_attention() {
        let context = AuditContext::new();

        let low_priority_payload = AuditPayload::CopybookParse {
            copybook_path: "test.cpy".to_string(),
            schema_fingerprint: "abc123".to_string(),
            parse_result: ParseResult::Success,
            parsing_duration_ms: 100,
            field_count: 10,
            level_88_count: 2,
            error_count: 0,
            warnings: vec![],
        };

        let low_event = AuditEvent::new(
            AuditEventType::CopybookParse,
            context.clone(),
            low_priority_payload,
        );

        assert!(!low_event.requires_immediate_attention());

        let high_priority_payload = AuditPayload::SecurityEvent {
            security_event_type: SecurityEventType::DataBreach,
            severity: "Critical".to_string(),
            affected_resources: vec!["customer_data".to_string()],
            threat_indicators: vec![],
            remediation_actions: vec![],
            incident_id: Some("INC-001".to_string()),
        };

        let high_event = AuditEvent::new(
            AuditEventType::SecurityEvent,
            context,
            high_priority_payload,
        );

        assert!(high_event.requires_immediate_attention());
    }

    #[test]
    fn test_audit_severity_display() {
        assert_eq!(AuditSeverity::Info.to_string(), "Info");
        assert_eq!(AuditSeverity::Low.to_string(), "Low");
        assert_eq!(AuditSeverity::Medium.to_string(), "Medium");
        assert_eq!(AuditSeverity::High.to_string(), "High");
        assert_eq!(AuditSeverity::Critical.to_string(), "Critical");
    }

    #[test]
    fn test_audit_severity_cef_numeric() {
        assert_eq!(AuditSeverity::Info.cef_numeric(), 1);
        assert_eq!(AuditSeverity::Low.cef_numeric(), 3);
        assert_eq!(AuditSeverity::Medium.cef_numeric(), 5);
        assert_eq!(AuditSeverity::High.cef_numeric(), 7);
        assert_eq!(AuditSeverity::Critical.cef_numeric(), 10);
    }

    #[test]
    fn test_audit_event_type_display() {
        assert_eq!(AuditEventType::SecurityEvent.to_string(), "SecurityEvent");
        assert_eq!(AuditEventType::CopybookParse.to_string(), "CopybookParse");
        assert_eq!(
            AuditEventType::DataTransformation.to_string(),
            "DataTransformation"
        );
    }
}