'use strict';

require('../common');
const assert = require('assert');

const LENGTH = 16;

const ab = new ArrayBuffer(LENGTH);
const dv = new DataView(ab);
const ui = new Uint8Array(ab);
const buf = Buffer.from(ab);


assert.ok(buf instanceof Buffer);
assert.strictEqual(buf.parent, buf.buffer);
assert.strictEqual(buf.buffer, ab);
assert.strictEqual(buf.length, ab.byteLength);


buf.fill(0xC);
for (let i = 0; i < LENGTH; i++) {
  assert.strictEqual(ui[i], 0xC);
  ui[i] = 0xF;
  assert.strictEqual(buf[i], 0xF);
}

buf.writeUInt32LE(0xF00, 0);
buf.writeUInt32BE(0xB47, 4);
buf.writeDoubleLE(3.1415, 8);

assert.strictEqual(dv.getUint32(0, true), 0xF00);
assert.strictEqual(dv.getUint32(4), 0xB47);
assert.strictEqual(dv.getFloat64(8, true), 3.1415);


// Now test protecting users from doing stupid things

assert.throws(function() {
  function AB() { }
  Object.setPrototypeOf(AB, ArrayBuffer);
  Object.setPrototypeOf(AB.prototype, ArrayBuffer.prototype);
  Buffer.from(new AB());
}, {
  code: 'ERR_INVALID_ARG_TYPE',
  name: 'TypeError [ERR_INVALID_ARG_TYPE]',
  message: 'The first argument must be one of type string, Buffer,' +
  ' ArrayBuffer, Array, or Array-like Object. Received type object'
});

// Test the byteOffset and length arguments
{
  const ab = new Uint8Array(5);
  ab[0] = 1;
  ab[1] = 2;
  ab[2] = 3;
  ab[3] = 4;
  ab[4] = 5;
  const buf = Buffer.from(ab.buffer, 1, 3);
  assert.strictEqual(buf.length, 3);
  assert.strictEqual(buf[0], 2);
  assert.strictEqual(buf[1], 3);
  assert.strictEqual(buf[2], 4);
  buf[0] = 9;
  assert.strictEqual(ab[1], 9);

  assert.throws(() => Buffer.from(ab.buffer, 6), {
    code: 'ERR_BUFFER_OUT_OF_BOUNDS',
    name: 'RangeError [ERR_BUFFER_OUT_OF_BOUNDS]',
    message: '"offset" is outside of buffer bounds'
  });
  assert.throws(() => Buffer.from(ab.buffer, 3, 6), {
    code: 'ERR_BUFFER_OUT_OF_BOUNDS',
    name: 'RangeError [ERR_BUFFER_OUT_OF_BOUNDS]',
    message: '"length" is outside of buffer bounds'
  });
}

// Test the deprecated Buffer() version also
{
  const ab = new Uint8Array(5);
  ab[0] = 1;
  ab[1] = 2;
  ab[2] = 3;
  ab[3] = 4;
  ab[4] = 5;
  const buf = Buffer(ab.buffer, 1, 3);
  assert.strictEqual(buf.length, 3);
  assert.strictEqual(buf[0], 2);
  assert.strictEqual(buf[1], 3);
  assert.strictEqual(buf[2], 4);
  buf[0] = 9;
  assert.strictEqual(ab[1], 9);

  assert.throws(() => Buffer(ab.buffer, 6), {
    code: 'ERR_BUFFER_OUT_OF_BOUNDS',
    name: 'RangeError [ERR_BUFFER_OUT_OF_BOUNDS]',
    message: '"offset" is outside of buffer bounds'
  });
  assert.throws(() => Buffer(ab.buffer, 3, 6), {
    code: 'ERR_BUFFER_OUT_OF_BOUNDS',
    name: 'RangeError [ERR_BUFFER_OUT_OF_BOUNDS]',
    message: '"length" is outside of buffer bounds'
  });
}

{
  // If byteOffset is not numeric, it defaults to 0.
  const ab = new ArrayBuffer(10);
  const expected = Buffer.from(ab, 0);
  assert.deepStrictEqual(Buffer.from(ab, 'fhqwhgads'), expected);
  assert.deepStrictEqual(Buffer.from(ab, NaN), expected);
  assert.deepStrictEqual(Buffer.from(ab, {}), expected);
  assert.deepStrictEqual(Buffer.from(ab, []), expected);

  // If byteOffset can be converted to a number, it will be.
  assert.deepStrictEqual(Buffer.from(ab, [1]), Buffer.from(ab, 1));

  // If byteOffset is Infinity, throw.
  assert.throws(() => {
    Buffer.from(ab, Infinity);
  }, {
    code: 'ERR_BUFFER_OUT_OF_BOUNDS',
    name: 'RangeError [ERR_BUFFER_OUT_OF_BOUNDS]',
    message: '"offset" is outside of buffer bounds'
  });
}

{
  // If length is not numeric, it defaults to 0.
  const ab = new ArrayBuffer(10);
  const expected = Buffer.from(ab, 0, 0);
  assert.deepStrictEqual(Buffer.from(ab, 0, 'fhqwhgads'), expected);
  assert.deepStrictEqual(Buffer.from(ab, 0, NaN), expected);
  assert.deepStrictEqual(Buffer.from(ab, 0, {}), expected);
  assert.deepStrictEqual(Buffer.from(ab, 0, []), expected);

  // If length can be converted to a number, it will be.
  assert.deepStrictEqual(Buffer.from(ab, 0, [1]), Buffer.from(ab, 0, 1));

  // If length is Infinity, throw.
  assert.throws(() => {
    Buffer.from(ab, 0, Infinity);
  }, {
    code: 'ERR_BUFFER_OUT_OF_BOUNDS',
    name: 'RangeError [ERR_BUFFER_OUT_OF_BOUNDS]',
    message: '"length" is outside of buffer bounds'
  });
}

// Test an array like entry with the length set to NaN.
assert.deepStrictEqual(Buffer.from({ length: NaN }), Buffer.alloc(0));
