// META: global=window,dedicatedworker
// META: script=/common/media.js
// META: script=/webcodecs/utils.js

var defaultInit = {
  timestamp: 1234,
  channels: 2,
  sampleRate: 8000,
  frames: 100,
};

function createDefaultAudioData() {
  return make_audio_data(
    defaultInit.timestamp,
    defaultInit.channels,
    defaultInit.sampleRate,
    defaultInit.frames
  );
}

test(t => {
  let local_data = new Float32Array(defaultInit.channels * defaultInit.frames);

  let audio_data_init = {
    timestamp: defaultInit.timestamp,
    data: local_data,
    numberOfFrames: defaultInit.frames,
    numberOfChannels: defaultInit.channels,
    sampleRate: defaultInit.sampleRate,
    format: 'f32-planar',
  }

  let data = new AudioData(audio_data_init);

  assert_equals(data.timestamp, defaultInit.timestamp, 'timestamp');
  assert_equals(data.numberOfFrames, defaultInit.frames, 'frames');
  assert_equals(data.numberOfChannels, defaultInit.channels, 'channels');
  assert_equals(data.sampleRate, defaultInit.sampleRate, 'sampleRate');
  assert_equals(
      data.duration, defaultInit.frames / defaultInit.sampleRate * 1_000_000,
      'duration');
  assert_equals(data.format, 'f32-planar', 'format');

  // Create an Int16 array of the right length.
  let small_data = new Int16Array(defaultInit.channels * defaultInit.frames);

  let wrong_format_init = {...audio_data_init};
  wrong_format_init.data = small_data;

  // Creating `f32-planar` AudioData from Int16 from should throw.
  assert_throws_js(TypeError, () => {
    let data = new AudioData(wrong_format_init);
  }, `AudioDataInit.data needs to be big enough`);

  var members = [
    'timestamp',
    'data',
    'numberOfFrames',
    'numberOfChannels',
    'sampleRate',
    'format',
  ];

  for (const member of members) {
    let incomplete_init = {...audio_data_init};
    delete incomplete_init[member];

    assert_throws_js(
        TypeError, () => {let data = new AudioData(incomplete_init)},
        'AudioData requires \'' + member + '\'');
  }

  let invalid_init = {...audio_data_init};
  invalid_init.numberOfFrames = 0

  assert_throws_js(
      TypeError, () => {let data = new AudioData(invalid_init)},
      'AudioData requires numberOfFrames > 0');

  invalid_init = {...audio_data_init};
  invalid_init.numberOfChannels = 0

  assert_throws_js(
      TypeError, () => {let data = new AudioData(invalid_init)},
      'AudioData requires numberOfChannels > 0');

}, 'Verify AudioData constructors');

test(t => {
  let data = createDefaultAudioData();
  data.close();
  assert_equals(data.sampleRate, 0);
  assert_equals(data.numberOfFrames, 0);
  assert_equals(data.numberOfChannels, 0);
  assert_equals(data.format, null);
}, 'AudioData close');

test(t => {
  let data = createDefaultAudioData();

  let clone = data.clone();

  // Verify the parameters match.
  assert_equals(data.timestamp, clone.timestamp, 'timestamp');
  assert_equals(data.numberOfFrames, clone.numberOfFrames, 'frames');
  assert_equals(data.numberOfChannels, clone.numberOfChannels, 'channels');
  assert_equals(data.sampleRate, clone.sampleRate, 'sampleRate');
  assert_equals(data.format, clone.format, 'format');

  const data_copyDest = new Float32Array(defaultInit.frames);
  const clone_copyDest = new Float32Array(defaultInit.frames);

  // Verify the data matches.
  for (var channel = 0; channel < defaultInit.channels; channel++) {
    data.copyTo(data_copyDest, {planeIndex: channel});
    clone.copyTo(clone_copyDest, {planeIndex: channel});

    assert_array_equals(
        data_copyDest, clone_copyDest, 'Cloned data ch=' + channel);
  }

  // Verify closing the original data doesn't close the clone.
  data.close();
  assert_equals(data.numberOfFrames, 0, 'data.buffer (closed)');
  assert_not_equals(clone.numberOfFrames, 0, 'clone.buffer (not closed)');

  clone.close();
  assert_equals(clone.numberOfFrames, 0, 'clone.buffer (closed)');

  // Verify closing a closed AudioData does not throw.
  data.close();
}, 'Verify closing and cloning AudioData');

test(t => {
  let data = make_audio_data(
      -10, defaultInit.channels, defaultInit.sampleRate, defaultInit.frames);
  assert_equals(data.timestamp, -10, 'timestamp');
  data.close();
}, 'Test we can construct AudioData with a negative timestamp.');

test(t => {
  var data = new Float32Array([0]);
  let audio_data_init = {
    timestamp: 0,
    data: data,
    numberOfFrames: 1,
    numberOfChannels: 1,
    sampleRate: 44100,
    format: 'f32',
  };
  let audioData = new AudioData(audio_data_init);
  assert_not_equals(data.length, 0, "Input data is copied when constructing an AudioData");
}, 'Test input array is copied on construction');

test(t => {
  let audio_data_init = {
    timestamp: 0,
    data: new Float32Array([1,2,3,4,5,6,7,8]),
    numberOfFrames: 4,
    numberOfChannels: 2,
    sampleRate: 44100,
    format: 'f32',
  };
  let audioData = new AudioData(audio_data_init);
  let dest = new Float32Array(8);
  assert_throws_js(
      RangeError, () => audioData.copyTo(dest, {planeIndex: 1}),
      'copyTo from interleaved data with non-zero planeIndex throws');
  audioData.close();
}, 'Test that copyTo throws if copying from interleaved with a non-zero planeIndex');

// Indices to pick a particular specific value in a specific sample-format
const MIN = 0; // Minimum sample value, max amplitude
const MAX = 1; // Maximum sample value, max amplitude
const HALF = 2; // Half the maximum sample value, positive
const NEGATIVE_HALF = 3; // Half the maximum sample value, negative
const BIAS = 4; // Center of the range, silence
const DISCRETE_STEPS = 5; // Number of different value for a type.

function pow2(p) {
  return 2 ** p;
}
// Rounding operations for conversion, currently always floor (round towards
// zero).
let r = Math.floor.bind(this);

const TEST_VALUES = {
  u8: [0, 255, 191, 64, 128, 256],
  s16: [
    -pow2(15),
    pow2(15) - 1,
    r((pow2(15) - 1) / 2),
    r(-pow2(15) / 2),
    0,
    pow2(16),
  ],
  s32: [
    -pow2(31),
    pow2(31) - 1,
    r((pow2(31) - 1) / 2),
    r(-pow2(31) / 2),
    0,
    pow2(32),
  ],
  f32: [-1.0, 1.0, 0.5, -0.5, 0, pow2(24)],
};

const TEST_TEMPLATE = {
  channels: 2,
  frames: 5,
  // Each test is run with an element of the cartesian product of a pair of
  // elements of the set of type in [u8, s16, s32, f32]
  // For each test, this template is copied and the values replaced with the
  // appropriate values for this particular type.
  // For each test, copy this template and replace the number by the appropriate
  // number for this type
  testInput: [MIN, BIAS, MAX, MIN, HALF, NEGATIVE_HALF, BIAS, MAX, BIAS, BIAS],
  testInterleavedResult: [MIN, NEGATIVE_HALF, BIAS, BIAS, MAX, MAX, MIN, BIAS, HALF, BIAS],
  testVectorInterleavedResult: [
    [MIN, MAX, HALF, BIAS, BIAS],
    [BIAS, MIN, NEGATIVE_HALF, MAX, BIAS],
  ],
  testVectorPlanarResult: [
    [MIN, BIAS, MAX, MIN, HALF],
    [NEGATIVE_HALF, BIAS, MAX, BIAS, BIAS],
  ],
};

function isInteger(type) {
  switch (type) {
    case "u8":
    case "s16":
    case "s32":
      return true;
    case "f32":
      return false;
    default:
      throw "invalid type";
  }
}

// This is the complex part: carefully select an acceptable error value
// depending on various factors: expected destination value, source type,
// destination type. This is designed to be strict but reachable with simple
// sample format transformation (no dithering or complex transformation).
function epsilon(expectedDestValue, sourceType, destType) {
  // Strict comparison if not converting
  if (sourceType == destType) {
    return 0.0;
  }
  // There are three cases in which the maximum value cannot be reached, when
  // converting from a smaller integer sample type to a wider integer sample
  // type:
  // - u8 to s16
  // - u8 to s32
  // - s16 to u32
  if (expectedDestValue == TEST_VALUES[destType][MAX]) {
    if (sourceType == "u8" && destType == "s16") {
      return expectedDestValue - 32511; // INT16_MAX - 2 << 7 + 1
    } else if (sourceType == "u8" && destType == "s32") {
      return expectedDestValue - 2130706432; // INT32_MAX - (2 << 23) + 1
    } else if (sourceType == "s16" && destType == "s32") {
      return expectedDestValue - 2147418112; // INT32_MAX - UINT16_MAX
    }
  }
  // Min and bias value are correctly mapped for all integer sample-types
  if (isInteger(sourceType) && isInteger(destType)) {
    if (expectedDestValue == TEST_VALUES[destType][MIN] ||
        expectedDestValue == TEST_VALUES[destType][BIAS]) {
      return 0.0;
    }
  }
  // If converting from float32 to u8 or s16, allow choosing the rounding
  // direction. s32 has higher resolution than f32 in [-1.0,1.0] (24 bits of
  // mantissa)
  if (!isInteger(sourceType) && isInteger(destType) && destType != "s32") {
    return 1.0;
  }
  // In all other cases, expect an accuracy that depends on the source type and
  // the destination type.
  // The resolution of the source type.
  var sourceResolution = TEST_VALUES[sourceType][DISCRETE_STEPS];
  // The resolution of the destination type.
  var destResolution = TEST_VALUES[destType][DISCRETE_STEPS];
  // Computations should be exact if going from high resolution to low resolution.
  if (sourceResolution > destResolution) {
    return 0.0;
  } else {
    // Something that approaches the precision imbalance
    return destResolution / sourceResolution;
  }
}

// Fill the template above with the values for a particular type
function get_type_values(type) {
  let cloned = structuredClone(TEST_TEMPLATE);
  cloned.testInput = Array.from(
    cloned.testInput,
    idx => TEST_VALUES[type][idx]
  );
  cloned.testInterleavedResult = Array.from(
    cloned.testInterleavedResult,
    idx => TEST_VALUES[type][idx]
  );
  cloned.testVectorInterleavedResult = Array.from(
    cloned.testVectorInterleavedResult,
    c => {
      return Array.from(c, idx => {
        return TEST_VALUES[type][idx];
      });
    }
  );
  cloned.testVectorPlanarResult = Array.from(
    cloned.testVectorPlanarResult,
    c => {
      return Array.from(c, idx => {
        return TEST_VALUES[type][idx];
      });
    }
  );
  return cloned;
}

function typeToArrayType(type) {
  switch (type) {
    case "u8":
      return Uint8Array;
    case "s16":
      return Int16Array;
    case "s32":
      return Int32Array;
    case "f32":
      return Float32Array;
    default:
      throw "Unexpected";
  }
}

function arrayTypeToType(array) {
  switch (array.constructor) {
    case Uint8Array:
      return "u8";
    case Int16Array:
      return "s16";
    case Int32Array:
      return "s32";
    case Float32Array:
      return "f32";
    default:
      throw "Unexpected";
  }
}

function check_array_equality(values, expected, sourceType, message, assert_func) {
  if (values.length != expected.length) {
    throw "Array not of the same length";
  }
  for (var i = 0; i < values.length; i++) {
    var eps = epsilon(expected[i], sourceType, arrayTypeToType(values));
    assert_func(
      Math.abs(expected[i] - values[i]) <= eps,
      `Got ${values[i]} but expected result ${
        expected[i]
      } at index ${i} when converting from ${sourceType} to ${arrayTypeToType(
        values
      )}, epsilon ${eps}`
    );
  }
  assert_func(
    true,
    `${values} is equal to ${expected} when converting from ${sourceType} to ${arrayTypeToType(
      values
    )}`
  );
}

function conversionTest(sourceType, destinationType) {
  test(function (t) {
    var test = get_type_values(sourceType);
    var result = get_type_values(destinationType);

    var sourceArrayCtor = typeToArrayType(sourceType);
    var destArrayCtor = typeToArrayType(destinationType);

    let data = new AudioData({
      timestamp: defaultInit.timestamp,
      data: new sourceArrayCtor(test.testInput),
      numberOfFrames: test.frames,
      numberOfChannels: test.channels,
      sampleRate: defaultInit.sampleRate,
      format: sourceType,
    });

    // All conversions can be supported, but conversion of any type to f32-planar
    // MUST be supported.
    var assert_func = destinationType == "f32" ? assert_true : assert_implements_optional;
    let dest = new destArrayCtor(data.numberOfFrames);
    data.copyTo(dest, { planeIndex: 0, format: destinationType + "-planar" });
    check_array_equality(
      dest,
      result.testVectorInterleavedResult[0],
      sourceType,
      "interleaved channel 0",
      assert_func
    );
    data.copyTo(dest, { planeIndex: 1, format: destinationType + "-planar" });
    check_array_equality(
      dest,
      result.testVectorInterleavedResult[1],
      sourceType,
      "interleaved channel 0",
      assert_func
    );
    let destInterleaved = new destArrayCtor(data.numberOfFrames * data.numberOfChannels);
    data.copyTo(destInterleaved, { planeIndex: 0, format: destinationType });
    check_array_equality(
      destInterleaved,
      result.testInput,
      sourceType,
      "copyTo from interleaved to interleaved (conversion only)",
      assert_implements_optional
    );

    data = new AudioData({
      timestamp: defaultInit.timestamp,
      data: new sourceArrayCtor(test.testInput),
      numberOfFrames: test.frames,
      numberOfChannels: test.channels,
      sampleRate: defaultInit.sampleRate,
      format: sourceType + "-planar",
    });

    data.copyTo(dest, { planeIndex: 0, format: destinationType + "-planar" });
    check_array_equality(
      dest,
      result.testVectorPlanarResult[0],
      sourceType,
      "planar channel 0",
      assert_func,
    );
    data.copyTo(dest, { planeIndex: 1, format: destinationType + "-planar" });
    check_array_equality(
      dest,
      result.testVectorPlanarResult[1],
      sourceType,
      "planar channel 1",
      assert_func
    );
    // Copy to interleaved from planar: all channels are copied
    data.copyTo(destInterleaved, {planeIndex: 0, format: destinationType});
    check_array_equality(
      destInterleaved,
      result.testInterleavedResult,
      sourceType,
      "planar to interleaved",
      assert_func
    );
  }, `Test conversion of ${sourceType} to ${destinationType}`);
}

const TYPES = ["u8", "s16", "s32", "f32"];
 TYPES.forEach(sourceType => {
   TYPES.forEach(destinationType => {
    conversionTest(sourceType, destinationType);
  });
});
