/**
 * Comprehensive TDD Test Suite for CoScientist Research Engine
 *
 * Following London School TDD with emphasis on property-based testing,
 * scientific methodology validation, and research workflow coordination.
 *
 * RED-GREEN-REFACTOR CYCLE:
 * Focus on hypothesis generation, experimental design validation,
 * statistical analysis coordination, and research reproducibility.
 */

import {
  describe,
  it,
  expect,
  beforeEach,
  afterEach,
  jest,
} from "@jest/globals";
import { EventEmitter } from "events";
import { CoScientistResearch } from "../co-scientist-research.js";
import {
  MockFactory,
  TestDataGenerator,
  MockBuilder,
  ContractTester,
  PerformanceTester,
  PropertyGenerator,
} from "./test-utilities.js";

// Mock external dependencies following London School principles
jest.mock("../../../utils/logger.js");
jest.mock("../../../ai/research-ai-engine.js");
jest.mock("../../../research/knowledge-base.js");

describe("CoScientistResearch - London School TDD with Property-Based Testing", () => {
  let coScientist: CoScientistResearch;
  let mockConfig: any;
  let mockLogger: jest.Mocked<any>;
  let mockAIEngine: jest.Mocked<any>;
  let mockExperimentEngine: jest.Mocked<any>;
  let mockAnalysisEngine: jest.Mocked<any>;
  let mockValidationEngine: jest.Mocked<any>;
  let mockKnowledgeBase: jest.Mocked<any>;
  let mockPerformanceMonitor: jest.Mocked<any>;
  let mockBuilder: MockBuilder;

  beforeEach(() => {
    // Setup comprehensive mock configuration for research engine
    mockConfig = {
      ai: {
        model: "co-scientist-v3",
        capabilities: [
          {
            domain: "chemistry",
            confidence: 0.92,
            methods: ["synthesis", "analysis", "optimization"],
            limitations: ["high_energy_reactions", "toxic_compounds"],
          },
          {
            domain: "biology",
            confidence: 0.88,
            methods: ["genomics", "proteomics", "systems_biology"],
            limitations: ["live_animal_studies", "clinical_trials"],
          },
          {
            domain: "physics",
            confidence: 0.85,
            methods: ["theoretical", "computational", "experimental"],
            limitations: ["particle_physics", "quantum_computing"],
          },
        ],
        reasoning: {
          causalInference: true,
          statisticalReasoning: true,
          scientificMethod: true,
          hypothesisGeneration: true,
        },
        learning: {
          continuousLearning: true,
          knowledgeUpdate: false,
          experienceRetention: true,
          crossDomainTransfer: true,
        },
      },
      experimentation: {
        design: {
          powerAnalysis: true,
          randomization: {
            method: "stratified",
            seed: 42,
            constraints: ["balanced_groups", "temporal_separation"],
          },
          controls: {
            enabled: true,
            types: ["negative", "positive", "vehicle"],
            matching: true,
          },
          blinding: {
            enabled: true,
            level: "double",
            methods: ["coded_samples", "independent_analysis"],
          },
        },
        execution: {
          automation: {
            enabled: true,
            platforms: ["opentrons", "hamilton", "tecan"],
            protocols: ["liquid_handling", "solid_phase_synthesis", "hplc"],
            safeguards: [
              "volume_checks",
              "contamination_prevention",
              "error_handling",
            ],
          },
          dataCollection: {
            realTime: true,
            validation: true,
            anonymization: true,
            standardization: true,
          },
          qualityControl: {
            checks: [
              {
                name: "reagent_quality",
                type: "statistical",
                parameters: { threshold: 0.95 },
                frequency: "per_batch",
              },
              {
                name: "instrument_calibration",
                type: "logical",
                parameters: { tolerance: 0.02 },
                frequency: "daily",
              },
            ],
            thresholds: [
              {
                metric: "purity",
                warning: 90,
                critical: 85,
                action: "flag_sample",
              },
              {
                metric: "yield",
                warning: 70,
                critical: 50,
                action: "repeat_experiment",
              },
            ],
            actions: [
              {
                trigger: "purity_below_critical",
                action: "abort",
                parameters: { notify_pi: true },
              },
              {
                trigger: "yield_below_warning",
                action: "adjust",
                parameters: { optimize_conditions: true },
              },
            ],
          },
        },
        safety: {
          enabled: true,
          protocols: [
            {
              domain: "chemistry",
              rules: [
                {
                  condition: "temperature > 200C",
                  action: "emergency_cooling",
                  severity: "high",
                },
                {
                  condition: "pressure > 10bar",
                  action: "pressure_release",
                  severity: "critical",
                },
              ],
              enforcement: "strict",
            },
          ],
          monitoring: {
            continuous: true,
            parameters: ["temperature", "pressure", "pH", "gas_levels"],
            thresholds: [
              { parameter: "temperature", limit: 250, action: "shutdown" },
              {
                parameter: "toxic_gas_ppm",
                limit: 10,
                action: "ventilation_increase",
              },
            ],
          },
          emergency: {
            stopConditions: [
              "fire_detected",
              "toxic_release",
              "equipment_failure",
            ],
            procedures: [
              {
                trigger: "fire_detected",
                steps: [
                  "shutdown_heating",
                  "activate_suppression",
                  "evacuate_area",
                ],
                timeout: 30000,
              },
            ],
            contacts: [
              {
                role: "safety_officer",
                contact: "safety@example.com",
                priority: 1,
              },
              {
                role: "principal_investigator",
                contact: "pi@example.com",
                priority: 2,
              },
            ],
          },
        },
      },
      analysis: {
        statistical: {
          methods: ["t_test", "anova", "regression", "non_parametric"],
          significance: 0.05,
          power: 0.8,
          corrections: ["bonferroni", "fdr", "holm"],
        },
        machine_learning: {
          algorithms: [
            "random_forest",
            "svm",
            "neural_network",
            "gradient_boosting",
          ],
          validation: {
            crossValidation: { folds: 5, stratified: true, repeats: 3 },
            holdout: {
              trainRatio: 0.7,
              validationRatio: 0.15,
              testRatio: 0.15,
            },
            bootstrap: { samples: 1000, confidence: 0.95 },
          },
          interpretation: {
            featureImportance: true,
            shap: true,
            lime: true,
            partialDependence: true,
          },
        },
        visualization: {
          interactive: true,
          formats: ["png", "svg", "pdf", "html"],
          themes: ["publication", "presentation", "web"],
          automation: true,
        },
        interpretation: {
          causalInference: true,
          effectSize: true,
          confidence: true,
          limitations: true,
        },
      },
      validation: {
        reproducibility: {
          required: true,
          standards: [
            "fair_principles",
            "open_science",
            "reproducible_research",
          ],
          documentation: {
            protocol: true,
            data: true,
            code: true,
            environment: true,
          },
          archival: {
            repositories: ["zenodo", "figshare", "dryad"],
            metadata: ["dublin_core", "datacite", "bioschemas"],
            access: "cc_by",
          },
        },
        peerReview: {
          enabled: false, // Disabled for automated testing
          reviewers: 2,
          criteria: [
            "methodology",
            "analysis",
            "interpretation",
            "reproducibility",
          ],
          blind: true,
        },
        metaAnalysis: {
          enabled: true,
          databases: ["pubmed", "web_of_science", "scopus"],
          criteria: {
            studyTypes: ["rct", "cohort", "case_control"],
            populations: ["human", "animal_model", "cell_culture"],
            interventions: ["chemical", "biological", "physical"],
            outcomes: ["primary", "secondary", "surrogate"],
          },
        },
      },
      knowledge: {
        sources: [
          {
            type: "database",
            name: "chembl",
            reliability: 0.95,
            coverage: ["chemistry", "pharmacology"],
          },
          {
            type: "literature",
            name: "pubmed",
            reliability: 0.9,
            coverage: ["biomedical", "life_sciences"],
          },
          {
            type: "database",
            name: "uniprot",
            reliability: 0.98,
            coverage: ["proteins", "genomics"],
          },
        ],
        integration: {
          ontologies: ["go", "chebi", "mesh"],
          standards: ["fair", "w3c", "obo"],
          mapping: true,
          validation: true,
        },
        updating: {
          frequency: "weekly",
          sources: ["api_feeds", "literature_alerts", "database_updates"],
          validation: true,
          versioning: true,
        },
        reasoning: {
          inference: true,
          consistency: true,
          uncertainty: true,
          explanation: true,
        },
      },
    };

    mockBuilder = new MockBuilder();

    // Setup Logger mock
    mockLogger = mockBuilder
      .mockFunction("info", jest.fn())
      .mockFunction("debug", jest.fn())
      .mockFunction("warn", jest.fn())
      .mockFunction("error", jest.fn())
      .build() as any;

    // Setup ResearchAIEngine mock
    mockAIEngine = {
      initialize: jest.fn().mockResolvedValue(undefined),
      generateHypotheses: jest
        .fn()
        .mockImplementation(async (domain, observations) => [
          {
            ...MockFactory.createResearchHypothesis(),
            statement: `Hypothesis generated from observations in ${domain}`,
            significance: 0.85 + Math.random() * 0.1,
          },
        ]),
      designMethodology: jest
        .fn()
        .mockImplementation(async (hypothesis, domain) => ({
          design: "experimental",
          sampling: {
            method: "stratified_random",
            size: 120,
            criteria: {
              inclusion: [`${domain}_samples`, "quality_assured"],
              exclusion: ["contaminated", "outliers"],
            },
          },
          analysis: {
            statistical: [
              {
                name: "anova",
                type: "parametric",
                assumptions: ["normality", "homogeneity", "independence"],
                parameters: { alpha: 0.05 },
              },
            ],
            significance: 0.05,
            power: 0.8,
            corrections: ["bonferroni"],
          },
          validation: {
            crossValidation: true,
            holdoutSet: 20,
            reproducibility: {
              seed: 42,
              environment: "controlled",
              dependencies: [`${domain}_toolkit==2.1.0`],
              documentation: true,
            },
          },
        })),
      checkConstraints: jest.fn().mockResolvedValue(true),
      drawConclusions: jest
        .fn()
        .mockImplementation(async (hypothesis, results) => [
          {
            statement: `Analysis supports ${hypothesis.statement}`,
            confidence: 0.82,
            evidence: [
              {
                type: "statistical",
                description: "Significant p-value in primary analysis",
                strength: 0.9,
                sources: ["experimental_data"],
              },
            ],
            implications: [
              "Further research recommended",
              "Clinical relevance potential",
            ],
          },
        ]),
      on: jest.fn(),
      emit: jest.fn(),
    };

    // Setup ExperimentEngine mock
    mockExperimentEngine = {
      initialize: jest.fn().mockResolvedValue(undefined),
      validateDesign: jest.fn().mockResolvedValue(undefined),
      execute: jest
        .fn()
        .mockImplementation(async (hypothesis, methodology) => ({
          raw: [
            {
              id: "dataset_primary",
              name: "Primary Experimental Data",
              type: "experimental",
              format: "csv",
              size: 2048576,
              path: "/data/primary.csv",
              checksum: "sha256:abc123",
            },
          ],
          processed: [
            {
              id: "dataset_processed",
              name: "Cleaned Experimental Data",
              type: "processed",
              format: "parquet",
              size: 1536000,
              path: "/data/processed.parquet",
              checksum: "sha256:def456",
            },
          ],
          quality: {
            completeness: 0.96,
            accuracy: 0.94,
            consistency: 0.91,
            validity: 0.95,
            issues: [
              {
                type: "missing_values",
                severity: "low",
                description: "4% missing values in secondary variables",
                location: "columns 15-18",
                resolution: "imputation_applied",
              },
            ],
          },
          metadata: {
            collection: {
              startDate: new Date("2024-01-15"),
              endDate: new Date("2024-02-28"),
              method: "automated_platform",
              instruments: ["hplc_system_1", "mass_spec_orbitrap"],
              conditions: ["temperature_controlled", "humidity_monitored"],
            },
            processing: {
              steps: [
                {
                  name: "quality_filter",
                  description: "Remove low quality samples",
                  timestamp: new Date("2024-03-01"),
                  parameters: { quality_threshold: 0.9 },
                },
              ],
              software: [
                { name: "pandas", version: "2.0.0", configuration: {} },
                { name: "scipy", version: "1.10.0", configuration: {} },
              ],
              parameters: {
                normalization: "z_score",
                filtering: {
                  method: "outlier_removal",
                  parameters: { threshold: 3.0 },
                  applied: true,
                },
                transformation: {
                  method: "log_transform",
                  parameters: { base: 10 },
                  applied: true,
                },
              },
            },
            variables: [
              {
                name: "reaction_yield",
                type: "continuous",
                unit: "percentage",
                range: [0, 100],
                missing: 2,
                distribution: {
                  type: "normal",
                  parameters: { mean: 78.5, std: 12.3 },
                  statistics: {
                    mean: 78.5,
                    median: 79.2,
                    mode: 80.1,
                    standardDeviation: 12.3,
                    variance: 151.29,
                    skewness: -0.15,
                    kurtosis: 0.23,
                  },
                },
              },
            ],
          },
        })),
      on: jest.fn(),
      emit: jest.fn(),
    };

    // Setup AnalysisEngine mock
    mockAnalysisEngine = {
      initialize: jest.fn().mockResolvedValue(undefined),
      validatePower: jest.fn().mockResolvedValue(undefined),
      analyze: jest
        .fn()
        .mockImplementation(async (data, hypothesis, methodology) => ({
          statistical: {
            tests: [
              {
                name: "one_way_anova",
                statistic: 15.67,
                pValue: 0.0023,
                confidence: { level: 0.95, lower: 2.1, upper: 8.9 },
                significant: true,
                effectSize: {
                  measure: "eta_squared",
                  value: 0.34,
                  interpretation: "large",
                },
              },
            ],
            models: [
              {
                name: "linear_regression",
                formula: "yield ~ temperature + concentration",
                coefficients: [
                  {
                    variable: "temperature",
                    estimate: 0.45,
                    standardError: 0.12,
                    tValue: 3.75,
                    pValue: 0.001,
                  },
                  {
                    variable: "concentration",
                    estimate: 1.23,
                    standardError: 0.28,
                    tValue: 4.39,
                    pValue: 0.0003,
                  },
                ],
                fit: {
                  rSquared: 0.67,
                  adjustedRSquared: 0.64,
                  aic: 145.2,
                  bic: 152.8,
                  logLikelihood: -69.6,
                },
                diagnostics: {
                  residuals: {
                    normality: {
                      test: "shapiro_wilk",
                      statistic: 0.96,
                      pValue: 0.15,
                      normal: true,
                    },
                    homoscedasticity: {
                      test: "breusch_pagan",
                      statistic: 2.31,
                      pValue: 0.13,
                      homoscedastic: true,
                    },
                    autocorrelation: {
                      test: "durbin_watson",
                      statistic: 1.89,
                      pValue: 0.24,
                      independent: true,
                    },
                  },
                  assumptions: {
                    linearity: true,
                    independence: true,
                    normality: true,
                    homoscedasticity: true,
                  },
                  outliers: [
                    {
                      index: 47,
                      value: 95.2,
                      leverage: 0.15,
                      residual: 2.8,
                      influence: 0.42,
                    },
                  ],
                },
              },
            ],
            summary: {
              hypothesisSupported: true,
              confidence: 0.87,
              powerAnalysis: {
                observedPower: 0.85,
                requiredSampleSize: 120,
                effectSize: 0.34,
                alpha: 0.05,
              },
              recommendations: [
                "Increase sample size for higher power",
                "Consider additional control variables",
                "Validate findings with independent dataset",
              ],
            },
          },
          ml: {
            models: [
              {
                name: "random_forest_regressor",
                algorithm: "ensemble",
                hyperparameters: {
                  n_estimators: 100,
                  max_depth: 10,
                  random_state: 42,
                },
                training: {
                  duration: 15.4,
                  iterations: 100,
                  convergence: true,
                  finalLoss: 0.23,
                },
                validation: {
                  metrics: [
                    {
                      name: "r2_score",
                      value: 0.73,
                      confidence: { level: 0.95, lower: 0.68, upper: 0.78 },
                    },
                    {
                      name: "rmse",
                      value: 6.8,
                      confidence: { level: 0.95, lower: 6.1, upper: 7.5 },
                    },
                  ],
                  confusionMatrix: undefined,
                  roc: undefined,
                },
              },
            ],
            performance: {
              bestModel: "random_forest_regressor",
              comparison: [
                {
                  model: "random_forest",
                  metric: "r2_score",
                  value: 0.73,
                  rank: 1,
                },
                {
                  model: "linear_regression",
                  metric: "r2_score",
                  value: 0.67,
                  rank: 2,
                },
              ],
              crossValidation: {
                folds: 5,
                mean: 0.71,
                std: 0.04,
                scores: [0.69, 0.73, 0.75, 0.68, 0.71],
              },
            },
            interpretation: {
              featureImportance: [
                { feature: "temperature", importance: 0.45, rank: 1 },
                { feature: "concentration", importance: 0.32, rank: 2 },
                { feature: "ph", importance: 0.18, rank: 3 },
              ],
              shap: {
                global: {
                  features: ["temperature", "concentration"],
                  values: [0.45, 0.32],
                  baseline: 75.2,
                },
                local: [
                  {
                    instance: 0,
                    features: ["temperature"],
                    values: [2.3],
                    prediction: 82.1,
                  },
                ],
              },
              partialDependence: [
                {
                  feature: "temperature",
                  values: [20, 30, 40, 50, 60],
                  dependence: [65.2, 72.8, 80.1, 85.4, 87.9],
                  ice: [
                    {
                      instance: 0,
                      values: [20, 30, 40],
                      curve: [63.1, 71.2, 79.3],
                    },
                  ],
                },
              ],
            },
          },
          causal: {
            causalGraph: {
              nodes: [
                { id: "temperature", name: "Temperature", type: "treatment" },
                { id: "yield", name: "Reaction Yield", type: "outcome" },
                {
                  id: "concentration",
                  name: "Concentration",
                  type: "confounder",
                },
              ],
              edges: [
                {
                  source: "temperature",
                  target: "yield",
                  type: "direct",
                  strength: 0.67,
                },
                {
                  source: "concentration",
                  target: "yield",
                  type: "direct",
                  strength: 0.43,
                },
              ],
              assumptions: [
                "no_unmeasured_confounders",
                "correct_functional_form",
              ],
            },
            effects: [
              {
                treatment: "temperature",
                outcome: "yield",
                effect: 0.45,
                confidence: { level: 0.95, lower: 0.21, upper: 0.69 },
                method: "instrumental_variables",
              },
            ],
            confounders: [
              {
                variable: "concentration",
                strength: 0.43,
                controlled: true,
                method: "regression_adjustment",
              },
            ],
          },
          visualization: {
            plots: [
              {
                id: "scatter_temp_yield",
                type: "scatter",
                title: "Temperature vs Yield",
                data: { x: "temperature", y: "yield" },
                config: {
                  theme: "publication",
                  interactive: false,
                  annotations: [
                    {
                      type: "trend_line",
                      content: "Linear fit: R² = 0.67",
                      position: { x: 0.7, y: 0.9 },
                    },
                  ],
                  styling: {
                    colors: ["#1f77b4", "#ff7f0e"],
                    fonts: { family: "Arial", size: 12, weight: "normal" },
                    layout: {
                      margin: { top: 20, right: 30, bottom: 40, left: 50 },
                      padding: { top: 10, right: 10, bottom: 10, left: 10 },
                      grid: true,
                    },
                  },
                },
                path: "/plots/scatter_temp_yield.png",
              },
            ],
            dashboard: {
              id: "analysis_dashboard",
              title: "Research Analysis Dashboard",
              widgets: [
                {
                  id: "summary_stats",
                  type: "table",
                  title: "Summary Statistics",
                  data: { rows: 10, cols: 5 },
                  position: { x: 0, y: 0, width: 6, height: 4 },
                },
              ],
              layout: { columns: 12, rows: 8, responsive: true },
            },
            reports: [
              {
                id: "analysis_report",
                title: "Statistical Analysis Report",
                format: "pdf",
                sections: [
                  {
                    title: "Executive Summary",
                    content:
                      "Temperature significantly affects reaction yield...",
                    figures: ["scatter_temp_yield"],
                    tables: ["summary_stats"],
                  },
                ],
                metadata: {
                  authors: ["AI Researcher"],
                  created: new Date(),
                  version: "1.0",
                  keywords: ["temperature", "yield", "analysis"],
                },
              },
            ],
          },
        })),
      on: jest.fn(),
      emit: jest.fn(),
    };

    // Setup ValidationEngine mock
    mockValidationEngine = {
      initialize: jest.fn().mockResolvedValue(undefined),
      checkEthics: jest.fn().mockResolvedValue(undefined),
      validateResults: jest
        .fn()
        .mockImplementation(async (results, methodology) => ({
          reproducibilityScore: 0.89,
          validationTests: [
            { name: "data_integrity", passed: true, score: 0.95 },
            { name: "methodology_compliance", passed: true, score: 0.87 },
            { name: "statistical_validity", passed: true, score: 0.91 },
          ],
          recommendations: [
            "Archive raw data with metadata",
            "Publish analysis code repository",
            "Consider replication by independent lab",
          ],
          certifications: ["fair_compliant", "open_science_ready"],
        })),
    };

    // Setup KnowledgeBase mock
    mockKnowledgeBase = {
      initialize: jest.fn().mockResolvedValue(undefined),
      getDomainKnowledge: jest.fn().mockImplementation(async (domain) => ({
        concepts: [`${domain}_fundamentals`, `${domain}_advanced_topics`],
        relationships: [`${domain}_cause_effect`, `${domain}_correlations`],
        methods: [`${domain}_standard_methods`, `${domain}_novel_approaches`],
        limitations: [
          `${domain}_known_constraints`,
          `${domain}_measurement_limits`,
        ],
        recentFindings: [
          {
            title: `Recent advances in ${domain}`,
            authors: ["Expert A", "Expert B"],
            year: 2024,
            relevance: 0.89,
          },
        ],
      })),
      getDomainConstraints: jest.fn().mockImplementation(async (domain) => ({
        ethical: [`${domain}_ethics`, "general_research_ethics"],
        technical: [
          `${domain}_equipment_limits`,
          `${domain}_measurement_precision`,
        ],
        regulatory: [`${domain}_compliance`, "institutional_requirements"],
        practical: [
          "budget_constraints",
          "time_limitations",
          "resource_availability",
        ],
      })),
    };

    // Setup ResearchPerformanceMonitor mock
    mockPerformanceMonitor = {
      start: jest.fn().mockResolvedValue(undefined),
      getMetrics: jest
        .fn()
        .mockResolvedValue(MockFactory.createPerformanceMetrics()),
      recordHypothesisGeneration: jest.fn(),
      recordExperimentExecution: jest.fn(),
      recordAnalysisCompletion: jest.fn(),
      recordValidationResults: jest.fn(),
    };

    // Mock constructor dependencies
    jest.mocked(require("../../../utils/logger.js")).Logger = jest
      .fn()
      .mockImplementation(() => mockLogger);

    // Create CoScientistResearch instance
    coScientist = new CoScientistResearch(mockConfig);

    // Inject mocks
    (coScientist as any).aiEngine = mockAIEngine;
    (coScientist as any).experimentEngine = mockExperimentEngine;
    (coScientist as any).analysisEngine = mockAnalysisEngine;
    (coScientist as any).validationEngine = mockValidationEngine;
    (coScientist as any).knowledgeBase = mockKnowledgeBase;
    (coScientist as any).performanceMonitor = mockPerformanceMonitor;
  });

  afterEach(() => {
    jest.clearAllMocks();
    mockBuilder.clear();
  });

  // ==================== INITIALIZATION BEHAVIOR ====================

  describe("Research Engine Initialization and Component Coordination", () => {
    it("should coordinate initialization of all research subsystems", async () => {
      // ARRANGE
      const initializeSpy = jest.spyOn(coScientist, "initialize");

      // ACT
      await coScientist.initialize();

      // ASSERT - Verify initialization coordination
      expect(initializeSpy).toHaveBeenCalledTimes(1);
      expect(mockKnowledgeBase.initialize).toHaveBeenCalled();
      expect(mockAIEngine.initialize).toHaveBeenCalled();
      expect(mockExperimentEngine.initialize).toHaveBeenCalled();
      expect(mockAnalysisEngine.initialize).toHaveBeenCalled();
      expect(mockValidationEngine.initialize).toHaveBeenCalled();
      expect(mockPerformanceMonitor.start).toHaveBeenCalled();
      expect(mockLogger.info).toHaveBeenCalledWith(
        "Initializing CoScientist Research Engine",
      );
    });

    it("should handle component initialization failures with proper error propagation", async () => {
      // ARRANGE
      const initError = new Error("Knowledge base initialization failed");
      mockKnowledgeBase.initialize.mockRejectedValueOnce(initError);

      // ACT & ASSERT
      await expect(coScientist.initialize()).rejects.toThrow(
        "Knowledge base initialization failed",
      );
      expect(mockLogger.error).toHaveBeenCalledWith(
        "Failed to initialize research engine",
        initError,
      );
    });

    it("should establish event handler contracts for research coordination", async () => {
      // ACT
      await coScientist.initialize();

      // ASSERT - Verify event handler setup
      expect(mockAIEngine.on).toHaveBeenCalledWith(
        "hypothesis:generated",
        expect.any(Function),
      );
      expect(mockExperimentEngine.on).toHaveBeenCalledWith(
        "experiment:completed",
        expect.any(Function),
      );
      expect(mockAnalysisEngine.on).toHaveBeenCalledWith(
        "analysis:completed",
        expect.any(Function),
      );
    });
  });

  // ==================== HYPOTHESIS GENERATION BEHAVIOR ====================

  describe("Hypothesis Generation with AI Coordination", () => {
    beforeEach(async () => {
      await coScientist.initialize();
    });

    it("should coordinate hypothesis generation with domain knowledge integration", async () => {
      // ARRANGE
      const domain = "chemistry";
      const observations = [
        "Reaction yield decreases at higher temperatures",
        "pH affects catalyst stability",
        "Solvent polarity influences product selectivity",
      ];

      // ACT
      const result = await coScientist.generateHypotheses(domain, observations);

      // ASSERT - Verify coordination
      expect(result.success).toBe(true);
      expect(result.data.length).toBeGreaterThan(0);
      expect(mockKnowledgeBase.getDomainKnowledge).toHaveBeenCalledWith(domain);
      expect(mockAIEngine.generateHypotheses).toHaveBeenCalledWith(
        domain,
        observations,
        expect.any(Object), // Domain knowledge
        undefined, // No constraints
      );
      expect(mockLogger.info).toHaveBeenCalledWith(
        "Generating research hypotheses",
        expect.objectContaining({
          domain,
          observationsCount: observations.length,
        }),
      );
    });

    it("should validate and rank generated hypotheses by significance", async () => {
      // ARRANGE
      const domain = "biology";
      const observations = ["Gene expression varies with environmental stress"];

      // Mock multiple hypotheses with different significance scores
      mockAIEngine.generateHypotheses.mockResolvedValueOnce([
        { ...MockFactory.createResearchHypothesis(), significance: 0.95 },
        { ...MockFactory.createResearchHypothesis(), significance: 0.78 },
        { ...MockFactory.createResearchHypothesis(), significance: 0.62 },
      ]);

      // ACT
      const result = await coScientist.generateHypotheses(domain, observations);

      // ASSERT
      expect(result.success).toBe(true);
      expect(result.data).toHaveLength(3);
      // Should be sorted by significance (descending)
      expect(result.data[0].significance).toBeGreaterThan(
        result.data[1].significance,
      );
      expect(result.data[1].significance).toBeGreaterThan(
        result.data[2].significance,
      );
    });

    // ==================== PROPERTY-BASED TESTING FOR HYPOTHESIS GENERATION ====================

    it("should generate valid hypotheses for any valid domain and observations", async () => {
      // ARRANGE - Property-based test inputs
      const validInputs = PropertyGenerator.generateTestCases(() => {
        const domains = [
          "chemistry",
          "biology",
          "physics",
          "materials",
          "environmental",
        ];
        const domain = domains[Math.floor(Math.random() * domains.length)];
        const observationCount = Math.floor(Math.random() * 5) + 1; // 1-5 observations
        const observations = Array.from(
          { length: observationCount },
          () =>
            `Observation about ${domain}: ${TestDataGenerator.randomString(20)}`,
        );
        return { domain, observations };
      }, 10);

      // ACT & ASSERT
      for (const { domain, observations } of validInputs) {
        const result = await coScientist.generateHypotheses(
          domain,
          observations,
        );

        expect(result.success).toBe(true);
        expect(result.data.length).toBeGreaterThan(0);
        expect(mockAIEngine.generateHypotheses).toHaveBeenCalledWith(
          domain,
          observations,
          expect.any(Object),
          undefined,
        );
      }
    });

    it("should handle constraint-based hypothesis generation", async () => {
      // ARRANGE
      const domain = "chemistry";
      const observations = ["Temperature affects reaction rate"];
      const constraints = {
        maxComplexity: 3,
        requireQuantitative: true,
        excludeHazardous: true,
        timeLimit: 30, // days
      };

      // ACT
      const result = await coScientist.generateHypotheses(
        domain,
        observations,
        constraints,
      );

      // ASSERT
      expect(result.success).toBe(true);
      expect(mockAIEngine.generateHypotheses).toHaveBeenCalledWith(
        domain,
        observations,
        expect.any(Object),
        constraints,
      );
    });
  });

  // ==================== PROJECT CREATION AND METHODOLOGY DESIGN ====================

  describe("Research Project Creation with Methodology Coordination", () => {
    beforeEach(async () => {
      await coScientist.initialize();
    });

    it("should coordinate project creation with AI-designed methodology", async () => {
      // ARRANGE
      const hypothesis = MockFactory.createResearchHypothesis();
      const title = "Temperature Effects on Catalytic Efficiency";
      const domain = "chemistry";

      // ACT
      const result = await coScientist.createProject(title, domain, hypothesis);

      // ASSERT
      expect(result.success).toBe(true);
      expect(result.data.title).toBe(title);
      expect(result.data.domain).toBe(domain);
      expect(result.data.status).toBe("design");
      expect(mockAIEngine.designMethodology).toHaveBeenCalledWith(
        hypothesis,
        domain,
      );
      expect(mockLogger.info).toHaveBeenCalledWith(
        "Creating research project",
        expect.objectContaining({ title, domain }),
      );
    });

    it("should validate project design with ethical and methodological checks", async () => {
      // ARRANGE
      const hypothesis = MockFactory.createResearchHypothesis();
      const title = "Ethical Validation Test";
      const domain = "biology";

      // ACT
      const result = await coScientist.createProject(title, domain, hypothesis);

      // ASSERT
      expect(result.success).toBe(true);
      expect(mockExperimentEngine.validateDesign).toHaveBeenCalled();
      expect(mockValidationEngine.checkEthics).toHaveBeenCalledWith(
        hypothesis,
        expect.any(Object), // Methodology
      );
      expect(mockAnalysisEngine.validatePower).toHaveBeenCalled();
    });

    it("should use provided partial methodology and complete it with AI", async () => {
      // ARRANGE
      const hypothesis = MockFactory.createResearchHypothesis();
      const title = "Partial Methodology Test";
      const domain = "physics";
      const partialMethodology = {
        design: "observational",
        sampling: {
          method: "convenience",
          size: 50,
        },
      };

      // ACT
      const result = await coScientist.createProject(
        title,
        domain,
        hypothesis,
        partialMethodology,
      );

      // ASSERT
      expect(result.success).toBe(true);
      expect(result.data.methodology.design).toBe("observational");
      expect(result.data.methodology.sampling.method).toBe("convenience");
      expect(result.data.methodology.sampling.size).toBe(50);
    });

    // ==================== PROPERTY-BASED TESTING FOR PROJECT PARAMETERS ====================

    it("should create valid projects for diverse research configurations", async () => {
      // ARRANGE - Property-based test cases
      const validProjectConfigs = PropertyGenerator.generateTestCases(() => {
        const domains = [
          "chemistry",
          "biology",
          "physics",
          "materials",
          "psychology",
        ];
        const designs = [
          "experimental",
          "observational",
          "theoretical",
          "computational",
        ];
        const sampleSizes = [30, 50, 100, 200, 500];

        return {
          title: `Study ${TestDataGenerator.randomString(8)}`,
          domain: domains[Math.floor(Math.random() * domains.length)],
          design: designs[Math.floor(Math.random() * designs.length)],
          sampleSize:
            sampleSizes[Math.floor(Math.random() * sampleSizes.length)],
        };
      }, 8);

      // ACT & ASSERT
      for (const config of validProjectConfigs) {
        const hypothesis = {
          ...MockFactory.createResearchHypothesis(),
          variables: [
            {
              name: "independent_var",
              type: "independent",
              dataType: "numerical",
              measurement: {
                unit: "units",
                scale: [0, 100],
                precision: 0.1,
                method: "measurement_device",
              },
            },
          ],
        };

        const methodology = {
          design: config.design,
          sampling: { method: "random", size: config.sampleSize },
        };

        const result = await coScientist.createProject(
          config.title,
          config.domain,
          hypothesis,
          methodology,
        );

        expect(result.success).toBe(true);
        expect(result.data.domain).toBe(config.domain);
        expect(result.data.methodology.design).toBe(config.design);
        expect(result.data.methodology.sampling.size).toBe(config.sampleSize);
      }
    });
  });

  // ==================== PROJECT EXECUTION ORCHESTRATION ====================

  describe("Research Project Execution Coordination", () => {
    let projectId: string;

    beforeEach(async () => {
      await coScientist.initialize();
      const project = await coScientist.createProject(
        "Execution Test Project",
        "chemistry",
        MockFactory.createResearchHypothesis(),
      );
      projectId = project.data!.id;
    });

    it("should coordinate project execution through all research phases", async () => {
      // ARRANGE
      const executeSpy = jest.spyOn(coScientist, "executeProject");

      // ACT
      const result = await coScientist.executeProject(projectId);

      // ASSERT
      expect(result.success).toBe(true);
      expect(executeSpy).toHaveBeenCalledWith(projectId);
      expect(mockLogger.info).toHaveBeenCalledWith(
        "Executing research project",
        expect.objectContaining({ projectId }),
      );
    });

    it("should coordinate experiment execution with data collection", async () => {
      // ARRANGE
      await coScientist.executeProject(projectId);
      const project = (await coScientist.getProject(projectId)).data!;

      // ACT - Wait for async execution to complete phases
      await new Promise((resolve) => setTimeout(resolve, 100));

      // ASSERT
      expect(mockExperimentEngine.execute).toHaveBeenCalledWith(
        project.hypothesis,
        project.methodology,
      );
      expect(
        mockPerformanceMonitor.recordExperimentExecution,
      ).toHaveBeenCalled();
    });

    it("should coordinate data analysis with statistical and ML methods", async () => {
      // ARRANGE
      await coScientist.executeProject(projectId);

      // ACT - Wait for async execution to complete
      await new Promise((resolve) => setTimeout(resolve, 100));

      // ASSERT
      expect(mockAnalysisEngine.analyze).toHaveBeenCalledWith(
        expect.any(Object), // Experimental data
        expect.any(Object), // Hypothesis
        expect.any(Object), // Methodology
      );
      expect(
        mockPerformanceMonitor.recordAnalysisCompletion,
      ).toHaveBeenCalled();
    });

    it("should coordinate AI-powered conclusion generation", async () => {
      // ARRANGE
      await coScientist.executeProject(projectId);

      // ACT - Wait for async execution
      await new Promise((resolve) => setTimeout(resolve, 100));

      // ASSERT
      expect(mockAIEngine.drawConclusions).toHaveBeenCalledWith(
        expect.any(Object), // Hypothesis
        expect.any(Object), // Analysis results
      );
    });

    it("should handle project execution failure with proper error management", async () => {
      // ARRANGE
      const executionError = new Error("Experiment execution failed");
      mockExperimentEngine.execute.mockRejectedValueOnce(executionError);

      // ACT
      await coScientist.executeProject(projectId);

      // Wait for async error handling
      await new Promise((resolve) => setTimeout(resolve, 100));

      // ASSERT
      const project = (await coScientist.getProject(projectId)).data!;
      expect(project.status).toBe("failed");
      expect(mockLogger.error).toHaveBeenCalledWith(
        "Project execution failed",
        expect.objectContaining({ projectId }),
      );
    });
  });

  // ==================== STATISTICAL ANALYSIS VALIDATION ====================

  describe("Statistical Analysis and Validation Coordination", () => {
    let projectId: string;

    beforeEach(async () => {
      await coScientist.initialize();
      const project = await coScientist.createProject(
        "Statistical Test Project",
        "biology",
        MockFactory.createResearchHypothesis(),
      );
      projectId = project.data!.id;

      // Complete project execution
      await coScientist.executeProject(projectId);
      await new Promise((resolve) => setTimeout(resolve, 100));
    });

    it("should coordinate comprehensive statistical validation", async () => {
      // ACT
      const result = await coScientist.validateResults(projectId);

      // ASSERT
      expect(result.success).toBe(true);
      expect(result.data.reproducibilityScore).toBeGreaterThan(0.8);
      expect(result.data.validationTests).toEqual(
        expect.arrayContaining([
          expect.objectContaining({ name: "data_integrity", passed: true }),
          expect.objectContaining({
            name: "methodology_compliance",
            passed: true,
          }),
          expect.objectContaining({
            name: "statistical_validity",
            passed: true,
          }),
        ]),
      );
      expect(mockValidationEngine.validateResults).toHaveBeenCalled();
    });

    it("should provide actionable recommendations for research improvement", async () => {
      // ACT
      const result = await coScientist.validateResults(projectId);

      // ASSERT
      expect(result.success).toBe(true);
      expect(result.data.recommendations).toEqual(
        expect.arrayContaining([
          "Archive raw data with metadata",
          "Publish analysis code repository",
          "Consider replication by independent lab",
        ]),
      );
      expect(result.data.certifications).toContain("fair_compliant");
    });

    // ==================== PROPERTY-BASED TESTING FOR STATISTICAL VALIDITY ====================

    it("should validate statistical results across different analysis methods", async () => {
      // ARRANGE - Property-based test for different statistical approaches
      const analysisConfigs = PropertyGenerator.generateTestCases(() => {
        const methods = [
          "t_test",
          "anova",
          "regression",
          "non_parametric",
          "bayesian",
        ];
        const significance = [0.01, 0.05, 0.1];
        const power = [0.8, 0.85, 0.9];

        return {
          method: methods[Math.floor(Math.random() * methods.length)],
          significance:
            significance[Math.floor(Math.random() * significance.length)],
          power: power[Math.floor(Math.random() * power.length)],
        };
      }, 6);

      // ACT & ASSERT
      for (const config of analysisConfigs) {
        // Mock analysis engine to return results for different methods
        mockAnalysisEngine.analyze.mockResolvedValueOnce({
          statistical: {
            tests: [
              {
                name: config.method,
                statistic: Math.random() * 10,
                pValue: Math.random() * config.significance,
                confidence: { level: 0.95, lower: 1.0, upper: 5.0 },
                significant: true,
              },
            ],
            models: [],
            summary: {
              hypothesisSupported: true,
              confidence: 0.85,
              powerAnalysis: {
                observedPower: config.power,
                requiredSampleSize: 100,
                effectSize: 0.5,
                alpha: config.significance,
              },
              recommendations: [],
            },
          },
          ml: { models: [], performance: {}, interpretation: {} },
          causal: {
            causalGraph: { nodes: [], edges: [], assumptions: [] },
            effects: [],
            confounders: [],
          },
          visualization: { plots: [], dashboard: {}, reports: [] },
        });

        const validationResult = await coScientist.validateResults(projectId);

        expect(validationResult.success).toBe(true);
        expect(validationResult.data.reproducibilityScore).toBeGreaterThan(0.7);
      }
    });
  });

  // ==================== MACHINE LEARNING INTEGRATION ====================

  describe("Machine Learning Analysis Integration", () => {
    beforeEach(async () => {
      await coScientist.initialize();
    });

    it("should coordinate ML model training with feature interpretation", async () => {
      // ARRANGE
      const project = await coScientist.createProject(
        "ML Integration Test",
        "chemistry",
        MockFactory.createResearchHypothesis(),
      );
      await coScientist.executeProject(project.data!.id);

      // Wait for execution
      await new Promise((resolve) => setTimeout(resolve, 100));

      // ASSERT
      expect(mockAnalysisEngine.analyze).toHaveBeenCalled();

      // Verify ML analysis was included
      const analysisCall = mockAnalysisEngine.analyze.mock.calls[0];
      expect(analysisCall).toBeDefined();
    });

    it("should provide interpretable ML results with SHAP values", async () => {
      // ARRANGE
      const project = await coScientist.createProject(
        "ML Interpretation Test",
        "biology",
        MockFactory.createResearchHypothesis(),
      );
      const projectId = project.data!.id;

      await coScientist.executeProject(projectId);
      await new Promise((resolve) => setTimeout(resolve, 100));

      // ACT
      const projectResult = await coScientist.getProject(projectId);
      const results = projectResult.data!.results!;

      // ASSERT
      expect(
        results.analysis.ml.interpretation.featureImportance,
      ).toBeDefined();
      expect(results.analysis.ml.interpretation.shap).toBeDefined();
      expect(
        results.analysis.ml.interpretation.partialDependence,
      ).toBeDefined();
    });

    // ==================== PROPERTY-BASED TESTING FOR ML CONFIGURATIONS ====================

    it("should handle diverse ML algorithm configurations", async () => {
      // ARRANGE - Property-based testing for ML configurations
      const mlConfigs = PropertyGenerator.generateTestCases(() => {
        const algorithms = [
          "random_forest",
          "svm",
          "neural_network",
          "gradient_boosting",
          "linear_regression",
        ];
        const validationMethods = ["cross_validation", "holdout", "bootstrap"];
        const interpretationMethods = [
          "shap",
          "lime",
          "permutation_importance",
        ];

        return {
          algorithm: algorithms[Math.floor(Math.random() * algorithms.length)],
          validation:
            validationMethods[
              Math.floor(Math.random() * validationMethods.length)
            ],
          interpretation:
            interpretationMethods[
              Math.floor(Math.random() * interpretationMethods.length)
            ],
        };
      }, 5);

      // ACT & ASSERT
      for (const config of mlConfigs) {
        const project = await coScientist.createProject(
          `ML Config Test ${config.algorithm}`,
          "chemistry",
          MockFactory.createResearchHypothesis(),
        );

        await coScientist.executeProject(project.data!.id);
        await new Promise((resolve) => setTimeout(resolve, 50));

        const projectResult = await coScientist.getProject(project.data!.id);

        // Should successfully create and execute project regardless of ML configuration
        expect(projectResult.success).toBe(true);
        expect(projectResult.data!.status).toBeOneOf([
          "execution",
          "analysis",
          "validation",
          "completed",
        ]);
      }
    });
  });

  // ==================== CAUSAL INFERENCE ANALYSIS ====================

  describe("Causal Inference and Reasoning", () => {
    beforeEach(async () => {
      await coScientist.initialize();
    });

    it("should coordinate causal graph construction with domain knowledge", async () => {
      // ARRANGE
      const hypothesis = {
        ...MockFactory.createResearchHypothesis(),
        statement: "Increased study time causes improved test scores",
      };

      const project = await coScientist.createProject(
        "Causal Inference Test",
        "psychology",
        hypothesis,
      );

      await coScientist.executeProject(project.data!.id);
      await new Promise((resolve) => setTimeout(resolve, 100));

      // ACT
      const projectResult = await coScientist.getProject(project.data!.id);
      const causalResults = projectResult.data!.results!.analysis.causal;

      // ASSERT
      expect(causalResults.causalGraph).toBeDefined();
      expect(causalResults.causalGraph.nodes.length).toBeGreaterThan(0);
      expect(causalResults.causalGraph.edges.length).toBeGreaterThan(0);
      expect(causalResults.effects.length).toBeGreaterThan(0);
      expect(causalResults.confounders).toBeDefined();
    });

    it("should identify and control for confounding variables", async () => {
      // ARRANGE
      const project = await coScientist.createProject(
        "Confounder Control Test",
        "epidemiology",
        MockFactory.createResearchHypothesis(),
      );

      await coScientist.executeProject(project.data!.id);
      await new Promise((resolve) => setTimeout(resolve, 100));

      // ACT
      const projectResult = await coScientist.getProject(project.data!.id);
      const confounders =
        projectResult.data!.results!.analysis.causal.confounders;

      // ASSERT
      expect(confounders).toEqual(
        expect.arrayContaining([
          expect.objectContaining({
            variable: expect.any(String),
            strength: expect.any(Number),
            controlled: true,
            method: expect.any(String),
          }),
        ]),
      );
    });
  });

  // ==================== PERFORMANCE AND SCALABILITY ====================

  describe("Performance Monitoring and Research Scalability", () => {
    beforeEach(async () => {
      await coScientist.initialize();
    });

    it("should monitor research pipeline performance metrics", async () => {
      // ARRANGE
      const project = await coScientist.createProject(
        "Performance Test",
        "chemistry",
        MockFactory.createResearchHypothesis(),
      );

      // ACT
      await coScientist.executeProject(project.data!.id);
      const metricsResult = await coScientist.getMetrics();

      // ASSERT
      expect(metricsResult.success).toBe(true);
      ContractTester.validatePerformanceMetrics(metricsResult.data);
      expect(mockPerformanceMonitor.getMetrics).toHaveBeenCalled();
    });

    it("should meet performance requirements for research operations", async () => {
      // ARRANGE & ACT
      const performanceTest = PerformanceTester.createPerformanceTest(
        "hypothesis_generation",
        () =>
          coScientist.generateHypotheses("chemistry", [
            "Temperature affects reaction rate",
          ]),
        1000, // 1 second max
        3, // 3 iterations
      );

      // ASSERT
      await performanceTest();
    });

    it("should handle concurrent research projects efficiently", async () => {
      // ARRANGE - Create multiple concurrent projects
      const concurrentProjects = Array.from({ length: 5 }, (_, i) =>
        coScientist.createProject(
          `Concurrent Project ${i}`,
          ["chemistry", "biology", "physics"][i % 3],
          MockFactory.createResearchHypothesis(),
        ),
      );

      // ACT
      const projects = await Promise.all(concurrentProjects);
      const executionPromises = projects
        .filter((p) => p.success)
        .map((p) => coScientist.executeProject(p.data!.id));

      await Promise.allSettled(executionPromises);

      // ASSERT
      const allProjects = await coScientist.listProjects();
      expect(allProjects.success).toBe(true);
      expect(allProjects.data.length).toBe(5);
    });
  });

  // ==================== CONTRACT AND ERROR HANDLING ====================

  describe("Contract Validation and Error Handling", () => {
    beforeEach(async () => {
      await coScientist.initialize();
    });

    it("should maintain service response contracts for all operations", async () => {
      // ARRANGE & ACT
      const hypothesesResult = await coScientist.generateHypotheses(
        "chemistry",
        ["Test observation"],
      );
      const projectResult = await coScientist.createProject(
        "Test",
        "biology",
        MockFactory.createResearchHypothesis(),
      );
      const listResult = await coScientist.listProjects();
      const metricsResult = await coScientist.getMetrics();

      // ASSERT
      ContractTester.validateServiceResponse(hypothesesResult);
      ContractTester.validateServiceResponse(projectResult);
      ContractTester.validateServiceResponse(listResult);
      ContractTester.validateServiceResponse(metricsResult);
    });

    it("should validate event emitter contract for research monitoring", async () => {
      // ARRANGE
      const expectedEvents = [
        "hypotheses:generated",
        "project:created",
        "project:started",
        "project:progress",
        "project:completed",
        "project:failed",
        "experiment:completed",
        "analysis:completed",
      ];

      // ACT & ASSERT
      ContractTester.validateEventEmitter(coScientist, expectedEvents);
    });

    it("should handle research validation failures gracefully", async () => {
      // ARRANGE
      const project = await coScientist.createProject(
        "Validation Failure Test",
        "chemistry",
        MockFactory.createResearchHypothesis(),
      );

      const validationError = new Error("Statistical validation failed");
      mockValidationEngine.validateResults.mockRejectedValueOnce(
        validationError,
      );

      // ACT
      const result = await coScientist.validateResults(project.data!.id);

      // ASSERT
      expect(result.success).toBe(false);
      expect(result.error?.code).toBe("VALIDATION_FAILED");
      expect(mockLogger.error).toHaveBeenCalledWith(
        "Failed to validate results",
        expect.objectContaining({ projectId: project.data!.id }),
      );
    });

    // ==================== PROPERTY-BASED ERROR TESTING ====================

    it("should handle various error scenarios robustly", async () => {
      // ARRANGE - Property-based error scenarios
      const errorScenarios = [
        {
          component: "aiEngine",
          method: "generateHypotheses",
          error: new Error("AI service timeout"),
        },
        {
          component: "experimentEngine",
          method: "execute",
          error: new Error("Equipment malfunction"),
        },
        {
          component: "analysisEngine",
          method: "analyze",
          error: new Error("Insufficient data"),
        },
        {
          component: "validationEngine",
          method: "validateResults",
          error: new Error("Validation criteria not met"),
        },
      ];

      // ACT & ASSERT
      for (const scenario of errorScenarios) {
        const mock = (coScientist as any)[scenario.component];
        mock[scenario.method].mockRejectedValueOnce(scenario.error);

        try {
          if (scenario.method === "generateHypotheses") {
            await coScientist.generateHypotheses("test", ["test"]);
          } else {
            const project = await coScientist.createProject(
              "Error Test",
              "chemistry",
              MockFactory.createResearchHypothesis(),
            );
            await coScientist.executeProject(project.data!.id);
            if (scenario.method === "validateResults") {
              await coScientist.validateResults(project.data!.id);
            }
          }
        } catch (error) {
          // Expected for some operations
        }

        expect(mockLogger.error).toHaveBeenCalled();

        // Reset mock for next iteration
        mock[scenario.method].mockReset();
        if (scenario.method === "generateHypotheses") {
          mock[scenario.method].mockResolvedValue([
            MockFactory.createResearchHypothesis(),
          ]);
        } else {
          mock[scenario.method].mockResolvedValue({});
        }
      }
    });
  });

  // ==================== RESEARCH REPRODUCIBILITY ====================

  describe("Research Reproducibility and Open Science", () => {
    beforeEach(async () => {
      await coScientist.initialize();
    });

    it("should generate FAIR-compliant research documentation", async () => {
      // ARRANGE
      const project = await coScientist.createProject(
        "FAIR Compliance Test",
        "chemistry",
        MockFactory.createResearchHypothesis(),
      );

      await coScientist.executeProject(project.data!.id);
      await new Promise((resolve) => setTimeout(resolve, 100));

      // ACT
      const validationResult = await coScientist.validateResults(
        project.data!.id,
      );

      // ASSERT
      expect(validationResult.success).toBe(true);
      expect(validationResult.data.certifications).toContain("fair_compliant");
      expect(validationResult.data.recommendations).toEqual(
        expect.arrayContaining([
          "Archive raw data with metadata",
          "Publish analysis code repository",
        ]),
      );
    });

    it("should support reproducible research workflows", async () => {
      // ARRANGE
      const reproducibleHypothesis = {
        ...MockFactory.createResearchHypothesis(),
        methodology: {
          ...MockFactory.createResearchHypothesis().methodology,
          validation: {
            crossValidation: true,
            holdoutSet: 20,
            reproducibility: {
              seed: 42,
              environment: "controlled_lab",
              dependencies: ["python==3.9", "numpy==1.21.0"],
              documentation: true,
            },
          },
        },
      };

      // ACT
      const project = await coScientist.createProject(
        "Reproducibility Test",
        "biology",
        reproducibleHypothesis,
      );

      // ASSERT
      expect(project.success).toBe(true);
      expect(project.data.methodology.validation.reproducibility).toBeDefined();
      expect(project.data.methodology.validation.reproducibility.seed).toBe(42);
    });
  });
});

/**
 * RED-GREEN-REFACTOR CYCLE DOCUMENTATION FOR COSCIENTIST RESEARCH:
 *
 * This comprehensive test suite demonstrates London School TDD applied to
 * scientific research automation and validation:
 *
 * 1. PROPERTY-BASED TESTING INTEGRATION:
 *    - Tests validate behavior across diverse input spaces
 *    - Hypothesis generation tested with various domains and observations
 *    - Statistical analysis validated across different methods and parameters
 *    - ML configurations tested with multiple algorithms and validation approaches
 *
 * 2. SCIENTIFIC METHODOLOGY VALIDATION:
 *    - All aspects of research pipeline tested: hypothesis → experiment → analysis → validation
 *    - Statistical validity, causal inference, and reproducibility requirements
 *    - AI integration for research enhancement and optimization
 *
 * 3. COMPLEX RESEARCH WORKFLOW COORDINATION:
 *    - Multi-phase research execution with proper error handling
 *    - Integration of traditional statistics with modern ML approaches
 *    - Knowledge base integration for domain-specific research guidance
 *
 * 4. LONDON SCHOOL PRINCIPLES IN SCIENTIFIC CONTEXT:
 *    - RED: Define expected scientific workflow behavior through failing tests
 *    - GREEN: Implement research coordination logic to satisfy scientific contracts
 *    - REFACTOR: Improve research workflow patterns while maintaining scientific rigor
 *
 * Key Scientific Collaboration Patterns Tested:
 * - AIEngine ↔ KnowledgeBase (hypothesis generation with domain knowledge)
 * - ExperimentEngine ↔ SafetySystem (automated experimentation with safety protocols)
 * - AnalysisEngine ↔ ValidationEngine (statistical analysis with reproducibility checks)
 * - MLEngine ↔ InterpretabilityTools (model training with explainable results)
 * - CausalInference ↔ DomainKnowledge (causal reasoning with scientific constraints)
 *
 * This design promotes rigorous scientific methodology while leveraging AI
 * for research acceleration and enhanced reproducibility.
 */
