import test from 'node:test';
import assert from 'node:assert/strict';
import os from 'os';
import path from 'path';

import { behaviorTracker } from './BehaviorTracker.js';
import { saveState } from './SaveState.js';

async function isolateSaveState(testId) {
  await saveState._writeQueue.catch(() => {});
  process.env.SAVE_DIR = path.join(os.tmpdir(), `sc-test-${testId}-${Date.now()}`);
  saveState._savePath = null;
  saveState._state = null;
  saveState._writeQueue = Promise.resolve();
}

test('initialize with explicit values', async () => {
  await isolateSaveState('behavior-explicit');
  behaviorTracker.initialize({ behavior: { curiosity: 30, obedience: 70, risk: 40, suspicion: 10 } });

  assert.deepEqual(behaviorTracker.getSnapshot(), {
    curiosity: 30,
    obedience: 70,
    risk: 40,
    suspicion: 10
  });
});

test('initialize with no behavior key uses defaults', async () => {
  await isolateSaveState('behavior-defaults');
  behaviorTracker.initialize({});

  assert.deepEqual(behaviorTracker.getSnapshot(), {
    curiosity: 50,
    obedience: 50,
    risk: 50,
    suspicion: 0
  });
});

test('apply adds positive delta', async () => {
  await isolateSaveState('behavior-positive-delta');
  behaviorTracker.initialize({ behavior: { curiosity: 60, obedience: 50, risk: 50, suspicion: 0 } });

  behaviorTracker.apply({ curiosity_delta: 5 });

  assert.equal(behaviorTracker.getSnapshot().curiosity, 65);
});

test('apply subtracts negative delta', async () => {
  await isolateSaveState('behavior-negative-delta');
  behaviorTracker.initialize({ behavior: { curiosity: 50, obedience: 50, risk: 50, suspicion: 0 } });

  behaviorTracker.apply({ curiosity_delta: -15 });

  assert.equal(behaviorTracker.getSnapshot().curiosity, 35);
});

test('apply clamps at 0', async () => {
  await isolateSaveState('behavior-clamp-low');
  behaviorTracker.initialize({ behavior: { curiosity: 5, obedience: 50, risk: 50, suspicion: 0 } });

  behaviorTracker.apply({ curiosity_delta: -20 });

  assert.equal(behaviorTracker.getSnapshot().curiosity, 0);
});

test('apply clamps at 100', async () => {
  await isolateSaveState('behavior-clamp-high');
  behaviorTracker.initialize({ behavior: { curiosity: 50, obedience: 50, risk: 95, suspicion: 0 } });

  behaviorTracker.apply({ risk_delta: 20 });

  assert.equal(behaviorTracker.getSnapshot().risk, 100);
});

test('setSnapshot overrides values', async () => {
  await isolateSaveState('behavior-set-snapshot');
  behaviorTracker.initialize({ behavior: { curiosity: 50, obedience: 50, risk: 50, suspicion: 0 } });

  behaviorTracker.setSnapshot({ curiosity: 80, obedience: 20 });
  const snapshot = behaviorTracker.getSnapshot();

  assert.equal(snapshot.curiosity, 80);
  assert.equal(snapshot.obedience, 20);
});

test('apply ignores non-numeric delta', async () => {
  await isolateSaveState('behavior-ignore-nonnumeric');
  behaviorTracker.initialize({ behavior: { curiosity: 50, obedience: 50, risk: 50, suspicion: 0 } });

  behaviorTracker.apply({ curiosity_delta: 'bad' });

  assert.equal(behaviorTracker.getSnapshot().curiosity, 50);
});
