/**
 * Integration tests for Chapman mechanism
 * Mirrors python/test/integration/test_chapman.py
 * Uses Node.js built-in test runner
 */

import { describe, it, before } from 'node:test';
import assert from 'node:assert';
import path from 'path';
import * as musica from '../../index.js';
import { isClose } from '../util/testUtils.js';

import { fileURLToPath } from 'url';

// Convert import.meta.url to a file path
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);

const { MICM, SolverType } = musica;

before(async () => {
  await musica.initModule();
});

/**
 * Test solver with Chapman mechanism
 * Equivalent to TestSolve in Python
 */
function testSolve(solver) {
    const state = solver.createState(1);

    const timeStep = 200.0;
    const temperature = 272.5;
    const pressure = 101253.3;

    const rateConstants = {
        'PHOTO.jO2': 2.42e-17,
        'PHOTO.jO3->O': 1.15e-5,
        'PHOTO.jO3->O1D': 6.61e-9
    };

    const initialConcentrations = {
        O2: 0.75,
        O: 0.0,
        O1D: 0.0,
        O3: 0.0000081
    };

    // Test setting int values (from Python test)
    state.setConditions({ temperatures: 272, pressures: 101325 });

    // Set actual test conditions
    state.setConditions({ temperatures: temperature, pressures: pressure });
    state.setConcentrations(initialConcentrations);
    state.setUserDefinedRateParameters(rateConstants);

    // Solve for one time step
    solver.solve(state, timeStep);
    const concentrations = state.getConcentrations();

    // Verify results match Python test expectations
    assert.ok(
        isClose(concentrations.O2[0], 0.75, 1e-5),
        `O2 concentration should be approximately 0.75, got ${concentrations.O2[0]}`
    );
    assert.ok(
        concentrations.O[0] > 0.0,
        `O concentration should be greater than 0, got ${concentrations.O[0]}`
    );
    assert.ok(
        concentrations.O1D[0] > 0.0,
        `O1D concentration should be greater than 0, got ${concentrations.O1D[0]}`
    );
    assert.ok(
        concentrations.O3[0] !== 0.0000081,
        `O3 concentration should have changed from initial value, got ${concentrations.O3[0]}`
    );
}

describe('Chapman mechanism with v0 config path', () => {
    it('should solve with v0 config directory', async (t) => {
        const configPath = path.join(__dirname, '../../../configs/v0/chapman');
        const solver = MICM.fromConfigPath(
            configPath,
            SolverType.rosenbrock_standard_order
        );
        testSolve(solver);
    });
});

describe('Chapman mechanism with v1 config files', () => {
    it('should solve with v1 JSON config file', async (t) => {
        const configPath = path.join(__dirname, '../../../configs/v1/chapman/config.json');
        const solver = MICM.fromConfigPath(
            configPath,
            SolverType.rosenbrock_standard_order
        );
        testSolve(solver);
    });

    it('should solve with v1 YAML config file', async (t) => {
        const configPath = path.join(__dirname, '../../../configs/v1/chapman/config.yaml');
        const solver = MICM.fromConfigPath(
            configPath,
            SolverType.rosenbrock_standard_order
        );
        testSolve(solver);
    });
});
