1use crate::colors;
2use crate::common_options::{get_optimized_reader, setup_automatic_optimization_config};
3use chrono;
4use clap::ArgMatches;
5use lawkit_core::common::output::OutputConfig;
6use lawkit_core::error::Result;
7use lawkit_core::laws::integration::AnalysisPurpose;
8use std::io::Write;
9
10pub fn get_numbers_from_input(matches: &ArgMatches) -> Result<Vec<f64>> {
11 let (_parallel_config, _memory_config) = setup_automatic_optimization_config();
12
13 let buffer = if let Some(input) = matches.get_one::<String>("input") {
14 if input == "-" {
15 get_optimized_reader(None)
16 } else {
17 get_optimized_reader(Some(input))
18 }
19 } else {
20 get_optimized_reader(None)
21 };
22
23 let data = buffer.map_err(|e| lawkit_core::error::BenfError::IoError(e.to_string()))?;
24
25 if data.trim().is_empty() {
26 return Err(lawkit_core::error::BenfError::ParseError(
27 "No input data provided".to_string(),
28 ));
29 }
30
31 lawkit_core::common::input::parse_text_input(&data)
32}
33
34pub fn get_dataset_name(matches: &ArgMatches) -> String {
35 matches
36 .get_one::<String>("input")
37 .cloned()
38 .unwrap_or_else(|| "stdin".to_string())
39}
40
41pub fn parse_analysis_purpose(purpose_str: &str) -> AnalysisPurpose {
42 match purpose_str {
43 "quality" => AnalysisPurpose::QualityAudit,
44 "fraud" => AnalysisPurpose::FraudDetection,
45 "concentration" => AnalysisPurpose::ConcentrationAnalysis,
46 "anomaly" => AnalysisPurpose::AnomalyDetection,
47 "distribution" => AnalysisPurpose::DistributionFitting,
48 _ => AnalysisPurpose::GeneralAnalysis,
49 }
50}
51
52pub fn output_integration_result(
54 writer: &mut Box<dyn Write>,
55 result: &lawkit_core::laws::integration::IntegrationResult,
56 config: &OutputConfig,
57) -> Result<()> {
58 match config.format.as_str() {
59 "json" => output_integration_json(writer, result),
60 "csv" => output_integration_csv(writer, result),
61 "yaml" => output_integration_yaml(writer, result),
62 _ => output_integration_text(writer, result, config),
63 }
64}
65
66fn output_integration_text(
67 writer: &mut Box<dyn Write>,
68 result: &lawkit_core::laws::integration::IntegrationResult,
69 config: &OutputConfig,
70) -> Result<()> {
71 if config.quiet {
72 writeln!(writer, "{:.3}", result.overall_quality_score)?;
73 return Ok(());
74 }
75
76 writeln!(writer, "Statistical Laws Integration Analysis")?;
77 writeln!(writer)?;
78
79 writeln!(
80 writer,
81 "{}: {}",
82 get_text("dataset", "en"),
83 result.dataset_name
84 )?;
85 writeln!(
86 writer,
87 "{}: {}",
88 get_text("numbers_analyzed", "en"),
89 result.numbers_analyzed
90 )?;
91 writeln!(
92 writer,
93 "{}: {} ({})",
94 get_text("laws_executed", "en"),
95 result.laws_executed.len(),
96 result.laws_executed.join(", ")
97 )?;
98
99 if let Some(ref focus) = result.focus {
100 writeln!(writer, "{}: {}", get_text("focus", "en"), focus)?;
101 }
102
103 writeln!(writer)?;
104
105 writeln!(writer, "{}:", get_text("integration_metrics", "en"))?;
106 writeln!(
107 writer,
108 " {}: {:.3}",
109 get_text("overall_quality", "en"),
110 result.overall_quality_score
111 )?;
112 writeln!(
113 writer,
114 " {}: {:.3}",
115 get_text("consistency", "en"),
116 result.consistency_score
117 )?;
118 writeln!(
119 writer,
120 " {}: {}",
121 get_text("conflicts_detected", "en"),
122 result.conflicts_detected
123 )?;
124 writeln!(
125 writer,
126 " {}: {:.3}",
127 get_text("recommendation_confidence", "en"),
128 result.recommendation_confidence
129 )?;
130 writeln!(writer)?;
131
132 writeln!(writer, "{}:", get_text("law_results", "en"))?;
133 for (law, score) in &result.law_scores {
134 let law_name = get_law_name(law, "en");
135 writeln!(writer, " {law_name}: {score:.3}")?;
136 }
137 writeln!(writer)?;
138
139 if !result.conflicts.is_empty() {
140 writeln!(writer, "{}:", get_text("conflicts", "en"))?;
141 for conflict in &result.conflicts {
142 writeln!(
143 writer,
144 " {}",
145 colors::level_conflict(&conflict.description)
146 )?;
147 writeln!(
148 writer,
149 " {}: {}",
150 get_text("cause", "en"),
151 conflict.likely_cause
152 )?;
153 writeln!(
154 writer,
155 " {}: {}",
156 get_text("suggestion", "en"),
157 conflict.resolution_suggestion
158 )?;
159 }
160 writeln!(writer)?;
161 }
162
163 writeln!(writer, "{}:", get_text("recommendations", "en"))?;
164 writeln!(
165 writer,
166 " FOCUS: {}: {}",
167 get_text("primary_law", "en"),
168 get_law_name(&result.recommendations.primary_law, "en")
169 )?;
170
171 if !result.recommendations.secondary_laws.is_empty() {
172 let secondary_names: Vec<String> = result
173 .recommendations
174 .secondary_laws
175 .iter()
176 .map(|law| get_law_name(law, "en"))
177 .collect();
178 writeln!(
179 writer,
180 " DETAIL: {}: {}",
181 get_text("secondary_laws", "en"),
182 secondary_names.join(", ")
183 )?;
184 }
185
186 writeln!(
187 writer,
188 " METRIC: {}: {}",
189 get_text("rationale", "en"),
190 result.recommendations.rationale
191 )?;
192 writeln!(writer)?;
193
194 if config.verbose {
195 output_verbose_integration_details(writer, result, "en")?;
196 }
197
198 Ok(())
199}
200
201fn output_integration_json(
202 writer: &mut Box<dyn Write>,
203 result: &lawkit_core::laws::integration::IntegrationResult,
204) -> Result<()> {
205 let _json_value = serde_json::json!({
206 "dataset": result.dataset_name,
207 "numbers_analyzed": result.numbers_analyzed,
208 "laws_executed": result.laws_executed,
209 "focus": result.focus,
210 "integration_metrics": {
211 "overall_quality_score": result.overall_quality_score,
212 "consistency_score": result.consistency_score,
213 "conflicts_detected": result.conflicts_detected,
214 "recommendation_confidence": result.recommendation_confidence
215 },
216 "law_scores": result.law_scores,
217 "conflicts": result.conflicts.iter().map(|c| {
218 serde_json::json!({
219 "type": format!("{:?}", c.conflict_type),
220 "laws_involved": c.laws_involved,
221 "conflict_score": c.conflict_score,
222 "description": c.description,
223 "likely_cause": c.likely_cause,
224 "resolution_suggestion": c.resolution_suggestion
225 })
226 }).collect::<Vec<_>>(),
227 "recommendations": {
228 "primary_law": result.recommendations.primary_law,
229 "secondary_laws": result.recommendations.secondary_laws,
230 "confidence": result.recommendations.confidence,
231 "rationale": result.recommendations.rationale
232 },
233 "overall_assessment": format!("{:?}", result.overall_assessment),
234 "risk_level": format!("{:?}", result.risk_level)
235 });
236
237 let enhanced_json = create_enhanced_integration_json(result);
238 writeln!(writer, "{}", serde_json::to_string_pretty(&enhanced_json)?)?;
239 Ok(())
240}
241
242fn create_enhanced_integration_json(
244 result: &lawkit_core::laws::integration::IntegrationResult,
245) -> serde_json::Value {
246 let basic_json = serde_json::json!({
248 "dataset": result.dataset_name,
249 "numbers_analyzed": result.numbers_analyzed,
250 "laws_executed": result.laws_executed,
251 "focus": result.focus,
252 "integration_metrics": {
253 "overall_quality_score": result.overall_quality_score,
254 "consistency_score": result.consistency_score,
255 "conflicts_detected": result.conflicts_detected,
256 "recommendation_confidence": result.recommendation_confidence
257 },
258 "law_scores": result.law_scores,
259 "conflicts": result.conflicts.iter().map(|c| {
260 serde_json::json!({
261 "type": format!("{:?}", c.conflict_type),
262 "laws_involved": c.laws_involved,
263 "conflict_score": c.conflict_score,
264 "description": c.description,
265 "likely_cause": c.likely_cause,
266 "resolution_suggestion": c.resolution_suggestion
267 })
268 }).collect::<Vec<_>>(),
269 "recommendations": {
270 "primary_law": result.recommendations.primary_law,
271 "secondary_laws": result.recommendations.secondary_laws,
272 "confidence": result.recommendations.confidence,
273 "rationale": result.recommendations.rationale
274 },
275 "overall_assessment": format!("{:?}", result.overall_assessment),
276 "risk_level": format!("{:?}", result.risk_level)
277 });
278
279 let mut enhanced_json = basic_json;
281
282 if let Some(law_scores_obj) = enhanced_json
284 .get_mut("law_scores")
285 .and_then(|v| v.as_object_mut())
286 {
287 for (law, score) in &result.law_scores {
288 if let Some(score_val) = law_scores_obj.get_mut(law) {
289 *score_val = serde_json::json!({
290 "score": score,
291 "tier": classify_score_tier(*score),
292 "interpretation": interpret_score(*score)
293 });
294 }
295 }
296 }
297
298 if let Some(conflicts_array) = enhanced_json
300 .get_mut("conflicts")
301 .and_then(|v| v.as_array_mut())
302 {
303 for (i, conflict) in result.conflicts.iter().enumerate() {
304 if let Some(conflict_obj) = conflicts_array.get_mut(i).and_then(|v| v.as_object_mut()) {
305 conflict_obj.insert(
306 "severity".to_string(),
307 serde_json::Value::String(
308 classify_conflict_severity(conflict.conflict_score).to_string(),
309 ),
310 );
311
312 if matches!(
314 conflict.conflict_type,
315 lawkit_core::laws::integration::ConflictType::ScoreDeviation
316 | lawkit_core::laws::integration::ConflictType::UnexpectedConsistency
317 ) {
318 conflict_obj.insert(
319 "detection_method".to_string(),
320 serde_json::Value::String("diffx-core structural analysis".to_string()),
321 );
322 }
323 }
324 }
325 }
326
327 enhanced_json.as_object_mut().unwrap().insert(
329 "metadata".to_string(),
330 serde_json::json!({
331 "tool": "lawkit",
332 "enhanced_with": "diffx-core",
333 "format_version": "2.2.0",
334 "generation_timestamp": chrono::Utc::now().to_rfc3339()
335 }),
336 );
337
338 enhanced_json
339}
340
341fn classify_score_tier(score: f64) -> &'static str {
343 match score {
344 s if s >= 0.9 => "excellent",
345 s if s >= 0.7 => "good",
346 s if s >= 0.5 => "fair",
347 s if s >= 0.3 => "poor",
348 _ => "very_poor",
349 }
350}
351
352fn interpret_score(score: f64) -> &'static str {
353 match score {
354 s if s >= 0.9 => "Strong adherence to statistical law",
355 s if s >= 0.7 => "Good fit with expected distribution",
356 s if s >= 0.5 => "Moderate alignment with pattern",
357 s if s >= 0.3 => "Weak correlation with expected behavior",
358 _ => "Minimal or no adherence to law",
359 }
360}
361
362fn classify_conflict_severity(score: f64) -> &'static str {
363 match score {
364 s if s >= 0.8 => "critical",
365 s if s >= 0.6 => "high",
366 s if s >= 0.4 => "medium",
367 s if s >= 0.2 => "low",
368 _ => "minimal",
369 }
370}
371
372fn output_integration_csv(
373 writer: &mut Box<dyn Write>,
374 result: &lawkit_core::laws::integration::IntegrationResult,
375) -> Result<()> {
376 writeln!(writer, "dataset,numbers_analyzed,laws_executed,focus,overall_quality_score,consistency_score,conflicts_detected,primary_law,overall_assessment,risk_level")?;
377 writeln!(
378 writer,
379 "{},{},{},{},{:.3},{:.3},{},{},{:?},{:?}",
380 result.dataset_name,
381 result.numbers_analyzed,
382 result.laws_executed.len(),
383 result.focus.as_deref().unwrap_or(""),
384 result.overall_quality_score,
385 result.consistency_score,
386 result.conflicts_detected,
387 result.recommendations.primary_law,
388 result.overall_assessment,
389 result.risk_level
390 )?;
391 Ok(())
392}
393
394fn output_integration_yaml(
395 writer: &mut Box<dyn Write>,
396 result: &lawkit_core::laws::integration::IntegrationResult,
397) -> Result<()> {
398 writeln!(writer, "dataset: \"{}\"", result.dataset_name)?;
399 writeln!(writer, "numbers_analyzed: {}", result.numbers_analyzed)?;
400 writeln!(writer, "laws_executed:")?;
401 for law in &result.laws_executed {
402 writeln!(writer, " - \"{law}\"")?;
403 }
404 if let Some(ref focus) = result.focus {
405 writeln!(writer, "focus: \"{focus}\"")?;
406 }
407 writeln!(writer, "integration_metrics:")?;
408 writeln!(
409 writer,
410 " overall_quality_score: {:.3}",
411 result.overall_quality_score
412 )?;
413 writeln!(
414 writer,
415 " consistency_score: {:.3}",
416 result.consistency_score
417 )?;
418 writeln!(
419 writer,
420 " conflicts_detected: {}",
421 result.conflicts_detected
422 )?;
423 writeln!(writer, "law_scores:")?;
424 for (law, score) in &result.law_scores {
425 writeln!(writer, " {law}: {score:.3}")?;
426 }
427 writeln!(writer, "recommendations:")?;
428 writeln!(
429 writer,
430 " primary_law: \"{}\"",
431 result.recommendations.primary_law
432 )?;
433 writeln!(
434 writer,
435 " confidence: {:.3}",
436 result.recommendations.confidence
437 )?;
438 Ok(())
439}
440
441fn output_verbose_integration_details(
443 writer: &mut Box<dyn Write>,
444 result: &lawkit_core::laws::integration::IntegrationResult,
445 _lang: &str,
446) -> Result<()> {
447 writeln!(writer, "=== {} ===", get_text("detailed_metrics", "en"))?;
448
449 output_data_characteristics(writer, result, "en")?;
450
451 if !result.recommendations.alternative_combinations.is_empty() {
452 output_alternative_combinations(writer, result, "en")?;
453 }
454
455 Ok(())
456}
457
458fn output_data_characteristics(
459 writer: &mut Box<dyn Write>,
460 result: &lawkit_core::laws::integration::IntegrationResult,
461 _lang: &str,
462) -> Result<()> {
463 let chars = &result.data_characteristics;
464
465 writeln!(writer, "{}:", get_text("data_characteristics", "en"))?;
466 writeln!(
467 writer,
468 " {}: {:?}",
469 get_text("data_type", "en"),
470 chars.data_type
471 )?;
472 writeln!(
473 writer,
474 " {}: {:?}",
475 get_text("distribution_shape", "en"),
476 chars.distribution_shape
477 )?;
478 writeln!(
479 writer,
480 " {}: {:?}",
481 get_text("outlier_presence", "en"),
482 chars.outlier_presence
483 )?;
484 writeln!(
485 writer,
486 " {}: {:?}",
487 get_text("scale_range", "en"),
488 chars.scale_range
489 )?;
490 writeln!(
491 writer,
492 " {}: {:?}",
493 get_text("sample_size_category", "en"),
494 chars.sample_size_category
495 )?;
496 writeln!(writer)?;
497
498 Ok(())
499}
500
501fn output_alternative_combinations(
502 writer: &mut Box<dyn Write>,
503 result: &lawkit_core::laws::integration::IntegrationResult,
504 _lang: &str,
505) -> Result<()> {
506 writeln!(writer, "{}:", get_text("alternative_combinations", "en"))?;
507
508 for combo in &result.recommendations.alternative_combinations {
509 writeln!(writer, "• {} ({})", combo.purpose, combo.laws.join(" + "))?;
510 writeln!(
511 writer,
512 " {}: {:.3}",
513 get_text("effectiveness", "en"),
514 combo.effectiveness_score
515 )?;
516 writeln!(
517 writer,
518 " {}: {}",
519 get_text("description", "en"),
520 combo.description
521 )?;
522 writeln!(writer)?;
523 }
524
525 Ok(())
526}
527
528fn get_text(key: &str, _lang: &str) -> String {
530 match key {
531 "integration_title" => "Integration Analysis Result",
532 "dataset" => "Dataset",
533 "numbers_analyzed" => "Numbers Analyzed",
534 "laws_executed" => "Laws Executed",
535 "integration_metrics" => "Integration Metrics",
536 "overall_quality" => "Overall Quality Score",
537 "consistency" => "Consistency Score",
538 "conflicts_detected" => "Conflicts Detected",
539 "recommendation_confidence" => "Recommendation Confidence",
540 "law_results" => "Law Results",
541 "conflicts" => "Conflicts",
542 "cause" => "Likely Cause",
543 "suggestion" => "Suggestion",
544 "recommendations" => "Recommendations",
545 "primary_law" => "Primary Law",
546 "secondary_laws" => "Secondary Laws",
547 "rationale" => "Rationale",
548 "focus" => "Focus",
549 "detailed_analysis" => "Detailed Analysis",
550 "detailed_metrics" => "Detailed Metrics",
551 "data_characteristics" => "Data Characteristics",
552 "data_type" => "Data Type",
553 "distribution_shape" => "Distribution Shape",
554 "outlier_presence" => "Outlier Presence",
555 "scale_range" => "Scale Range",
556 "sample_size_category" => "Sample Size Category",
557 "alternative_combinations" => "Alternative Combinations",
558 "effectiveness" => "Effectiveness",
559 "description" => "Description",
560 _ => key,
561 }
562 .to_string()
563}
564
565fn get_law_name(law: &str, _lang: &str) -> String {
566 match law {
567 "benf" => "Benford Law",
568 "pareto" => "Pareto Principle",
569 "zipf" => "Zipf Law",
570 "normal" => "Normal Distribution",
571 "poisson" => "Poisson Distribution",
572 _ => law,
573 }
574 .to_string()
575}