import assert from 'node:assert/strict';
import fs from 'node:fs/promises';
import path from 'node:path';
import test from 'node:test';
import vm from 'node:vm';

const root = path.resolve(import.meta.dirname, '..');

async function source() {
  return fs.readFile(path.join(root, 'public/js/vibration.js'), 'utf8');
}

test('legacy vibration patterns are exposed as immutable constants', async () => {
  const calls = [];
  const context = {
    navigator: { vibrate: pattern => { calls.push(pattern); return true; } },
    Wegwichtel: {}
  };

  vm.runInNewContext(await source(), context);
  const vibration = context.Wegwichtel.Vibration;

  assert.equal(vibration.Patterns.MICRO, 50);
  assert.equal(vibration.Patterns.MINI, 100);
  assert.equal(vibration.Patterns.SHORT, 200);
  assert.equal(vibration.Patterns.LONG, 2000);
  assert.deepEqual(Array.from(vibration.Patterns.ALARM), [100, 50, 100]);
  assert.deepEqual(Array.from(vibration.Patterns.POI), [2000, 200, 2000]);
  assert.deepEqual(Array.from(vibration.Patterns.ACTIVE_POI), [500, 300, 500]);
  assert.equal(Object.isFrozen(vibration.Patterns), true);
});

test('vibration wrapper starts named patterns and can cancel them', async () => {
  const calls = [];
  const context = {
    navigator: { vibrate: pattern => { calls.push(pattern); return true; } },
    Wegwichtel: {}
  };

  vm.runInNewContext(await source(), context);
  const vibration = context.Wegwichtel.Vibration;

  assert.equal(vibration.start(vibration.Patterns.ACTIVE_POI), true);
  assert.equal(vibration.start(vibration.Patterns.SHORT), true);
  assert.equal(vibration.stop(), true);
  assert.deepEqual(Array.from(calls[0]), [500, 300, 500]);
  assert.deepEqual(Array.from(calls[1]), [200]);
  assert.equal(calls[2], 0);
});

test('vibration wrapper fails harmlessly when the browser API is unavailable', async () => {
  const context = {
    navigator: {},
    Wegwichtel: {}
  };

  vm.runInNewContext(await source(), context);
  const vibration = context.Wegwichtel.Vibration;

  assert.equal(vibration.isSupported(), false);
  assert.equal(vibration.start(vibration.Patterns.SHORT), false);
  assert.equal(vibration.stop(), false);
});
