// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.

'use strict';
require('../common');
const assert = require('assert');
// Minimum string size to overflow into external string space
const EXTERN_APEX = 0xFBEE9;

// Manually controlled string for checking binary output
let ucs2_control = 'a\u0000';
let write_str = 'a';


// First do basic checks
let b = Buffer.from(write_str, 'ucs2');
// first check latin1
let c = b.toString('latin1');
assert.strictEqual(b[0], 0x61);
assert.strictEqual(b[1], 0);
assert.strictEqual(ucs2_control, c);
// now check binary
c = b.toString('binary');
assert.strictEqual(b[0], 0x61);
assert.strictEqual(b[1], 0);
assert.strictEqual(ucs2_control, c);

// Now create big strings
const size = 1 << 20;
write_str = write_str.repeat(size);
ucs2_control = ucs2_control.repeat(size);

// Check resultant buffer and output string
b = Buffer.from(write_str, 'ucs2');
// Check fist Buffer created from write string
for (let i = 0; i < b.length; i += 2) {
  assert.strictEqual(b[i], 0x61);
  assert.strictEqual(b[i + 1], 0);
}

// Create another string to create an external string
const b_ucs = b.toString('ucs2');

// Check control against external binary string
const l_bin = b.toString('latin1');
assert.strictEqual(ucs2_control, l_bin);

// Check control against external binary string
const b_bin = b.toString('binary');
assert.strictEqual(ucs2_control, b_bin);

// Create buffer copy from external
const c_bin = Buffer.from(l_bin, 'latin1');
const c_ucs = Buffer.from(b_ucs, 'ucs2');
// Make sure they're the same length
assert.strictEqual(c_bin.length, c_ucs.length);
// Make sure Buffers from externals are the same
for (let i = 0; i < c_bin.length; i++) {
  assert.strictEqual(c_bin[i], c_ucs[i]);
}
// Check resultant strings
assert.strictEqual(c_bin.toString('ucs2'), c_ucs.toString('ucs2'));
assert.strictEqual(c_bin.toString('latin1'), ucs2_control);
assert.strictEqual(c_ucs.toString('latin1'), ucs2_control);


// Now let's test BASE64 and HEX encoding/decoding
const RADIOS = 2;
const PRE_HALF_APEX = Math.ceil(EXTERN_APEX / 2) - RADIOS;
const PRE_3OF4_APEX = Math.ceil((EXTERN_APEX / 4) * 3) - RADIOS;

{
  for (let j = 0; j < RADIOS * 2; j += 1) {
    const datum = b;
    const slice = datum.slice(0, PRE_HALF_APEX + j);
    const slice2 = datum.slice(0, PRE_HALF_APEX + j + 2);
    const pumped_string = slice.toString('hex');
    const pumped_string2 = slice2.toString('hex');
    const decoded = Buffer.from(pumped_string, 'hex');

    // The string are the same?
    for (let k = 0; k < pumped_string.length; ++k) {
      assert.strictEqual(pumped_string[k], pumped_string2[k]);
    }

    // The recoded buffer is the same?
    for (let i = 0; i < decoded.length; ++i) {
      assert.strictEqual(datum[i], decoded[i]);
    }
  }
}

{
  for (let j = 0; j < RADIOS * 2; j += 1) {
    const datum = b;
    const slice = datum.slice(0, PRE_3OF4_APEX + j);
    const slice2 = datum.slice(0, PRE_3OF4_APEX + j + 2);
    const pumped_string = slice.toString('base64');
    const pumped_string2 = slice2.toString('base64');
    const decoded = Buffer.from(pumped_string, 'base64');

    // The string are the same?
    for (let k = 0; k < pumped_string.length - 3; ++k) {
      assert.strictEqual(pumped_string[k], pumped_string2[k]);
    }

    // The recoded buffer is the same?
    for (let i = 0; i < decoded.length; ++i) {
      assert.strictEqual(datum[i], decoded[i]);
    }
  }
}

// https://github.com/nodejs/node/issues/1024
{
  const a = 'x'.repeat(1 << 20 - 1);
  const b = Buffer.from(a, 'ucs2').toString('ucs2');
  const c = Buffer.from(b, 'utf8').toString('utf8');

  assert.strictEqual(a.length, b.length);
  assert.strictEqual(b.length, c.length);

  assert.strictEqual(a, b);
  assert.strictEqual(b, c);
}
