import assert from 'node:assert/strict';
import test from 'node:test';
import {
  AUDIO_ANALYSIS_JOB_OPTIONS,
  AUDIO_ANALYSIS_VERSION,
  audioAnalysisJobId,
  normaliseDanceability,
  normaliseMeanSquareEnergy,
  validBpm,
  validKey,
} from './audio-analysis.js';

test('maps mean-square energy through a dBFS range instead of saturating mastered tracks', () => {
  assert.equal(normaliseMeanSquareEnergy(-1), null);
  assert.equal(normaliseMeanSquareEnergy(0), 0);
  assert.ok(Math.abs((normaliseMeanSquareEnergy(0.0001) ?? 0) - 8 / 42) < 0.000001); // -40 dBFS
  assert.ok(Math.abs((normaliseMeanSquareEnergy(0.01) ?? 0) - 28 / 42) < 0.000001); // -20 dBFS
  assert.equal(normaliseMeanSquareEnergy(0.26), 1); // above the -6 dBFS ceiling
});

test('only accepts values that are safe for Vibe consumers and database constraints', () => {
  assert.equal(validBpm(29.9), null);
  assert.equal(validBpm(128.04), 128);
  assert.equal(validBpm(300.1), null);
  assert.equal(validKey(' 8A '), '8A');
  assert.equal(validKey(' '.repeat(33)), null);
  assert.equal(normaliseDanceability(-0.1), null);
  assert.equal(normaliseDanceability(1.5), 0.5);
  assert.equal(normaliseDanceability(9), 1);
});

test('uses a versioned, retryable, deduplicated job contract', () => {
  assert.equal(AUDIO_ANALYSIS_VERSION, 2);
  assert.equal(audioAnalysisJobId('track-1'), 'audio-track-1');
  assert.equal(AUDIO_ANALYSIS_JOB_OPTIONS.attempts, 3);
  assert.deepEqual(AUDIO_ANALYSIS_JOB_OPTIONS.backoff, { type: 'exponential', delay: 5_000 });
});
