import assert from 'node:assert/strict';
import test from 'node:test';
import { parseAcquisitionSpec, validateAcquisitionUrl } from './acquisition.service.js';

const HOSTS = new Set(['www.youtube.com']);

test('accepts an allow-listed HTTPS url', () => {
  const spec = parseAcquisitionSpec(
    { acquisition: { url: 'https://www.youtube.com/watch?v=abc', expectedTitle: 'T', expectedArtist: 'A' } },
    HOSTS
  );
  assert.equal(spec.url, 'https://www.youtube.com/watch?v=abc');
  assert.equal(spec.query, undefined);
  assert.equal(spec.expectedArtist, 'A');
});

test('accepts a search query and strips newlines that could forge print output', () => {
  const spec = parseAcquisitionSpec(
    { acquisition: { query: 'Boards of Canada\nRoygbiv', expectedTitle: 'Roygbiv' } },
    HOSTS
  );
  assert.equal(spec.query, 'Boards of Canada Roygbiv');
  assert.equal(spec.url, undefined);
});

test('rejects a candidate naming neither a url nor a query', () => {
  assert.throws(() => parseAcquisitionSpec({ acquisition: { expectedTitle: 'T' } }, HOSTS), /url or a query/);
  assert.throws(() => parseAcquisitionSpec({ acquisition: { query: '   ' } }, HOSTS), /url or a query/);
  assert.throws(() => parseAcquisitionSpec({}, HOSTS), /no resolved acquisition source/);
});

test('search-resolved urls face the same gates as supplied ones', () => {
  assert.throws(() => validateAcquisitionUrl('https://evil.example/x', HOSTS), /not allow-listed/);
  assert.throws(() => validateAcquisitionUrl('http://www.youtube.com/x', HOSTS), /must use HTTPS/);
  assert.throws(() => validateAcquisitionUrl('https://u:p@www.youtube.com/x', HOSTS), /must not contain credentials/);
  assert.equal(
    validateAcquisitionUrl('https://WWW.YouTube.com/watch?v=1', HOSTS),
    'https://www.youtube.com/watch?v=1'
  );
});
