// 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';
const common = require('../common');
const tmpdir = require('../common/tmpdir');

const child_process = require('child_process');
const assert = require('assert');
const fs = require('fs');
const fixtures = require('../common/fixtures');

const fn = fixtures.path('elipses.txt');
const rangeFile = fixtures.path('x.txt');

function test1(options) {
  let paused = false;
  let bytesRead = 0;

  const file = fs.createReadStream(fn, options);
  const fileSize = fs.statSync(fn).size;

  assert.strictEqual(file.bytesRead, 0);

  file.on('open', common.mustCall(function(fd) {
    file.length = 0;
    assert.strictEqual(typeof fd, 'number');
    assert.strictEqual(file.bytesRead, 0);
    assert.ok(file.readable);

    // GH-535
    file.pause();
    file.resume();
    file.pause();
    file.resume();
  }));

  file.on('data', function(data) {
    assert.ok(data instanceof Buffer);
    assert.ok(data.byteOffset % 8 === 0);
    assert.ok(!paused);
    file.length += data.length;

    bytesRead += data.length;
    assert.strictEqual(file.bytesRead, bytesRead);

    paused = true;
    file.pause();

    setTimeout(function() {
      paused = false;
      file.resume();
    }, 10);
  });


  file.on('end', common.mustCall(function(chunk) {
    assert.strictEqual(bytesRead, fileSize);
    assert.strictEqual(file.bytesRead, fileSize);
  }));


  file.on('close', common.mustCall(function() {
    assert.strictEqual(bytesRead, fileSize);
    assert.strictEqual(file.bytesRead, fileSize);
  }));

  process.on('exit', function() {
    assert.strictEqual(file.length, 30000);
  });
}

test1({});
test1({
  fs: {
    open: common.mustCall(fs.open),
    read: common.mustCallAtLeast(fs.read, 1),
    close: common.mustCall(fs.close),
  }
});

{
  const file = fs.createReadStream(fn, { encoding: 'utf8' });
  file.length = 0;
  file.on('data', function(data) {
    assert.strictEqual(typeof data, 'string');
    file.length += data.length;

    for (let i = 0; i < data.length; i++) {
      // http://www.fileformat.info/info/unicode/char/2026/index.htm
      assert.strictEqual(data[i], '\u2026');
    }
  });

  file.on('close', common.mustCall());

  process.on('exit', function() {
    assert.strictEqual(file.length, 10000);
  });
}

{
  const file =
    fs.createReadStream(rangeFile, { bufferSize: 1, start: 1, end: 2 });
  let contentRead = '';
  file.on('data', function(data) {
    contentRead += data.toString('utf-8');
  });
  file.on('end', common.mustCall(function(data) {
    assert.strictEqual(contentRead, 'yz');
  }));
}

{
  const file = fs.createReadStream(rangeFile, { bufferSize: 1, start: 1 });
  file.data = '';
  file.on('data', function(data) {
    file.data += data.toString('utf-8');
  });
  file.on('end', common.mustCall(function() {
    assert.strictEqual(file.data, 'yz\n');
  }));
}

{
  // Ref: https://github.com/nodejs/node-v0.x-archive/issues/2320
  const file = fs.createReadStream(rangeFile, { bufferSize: 1.23, start: 1 });
  file.data = '';
  file.on('data', function(data) {
    file.data += data.toString('utf-8');
  });
  file.on('end', common.mustCall(function() {
    assert.strictEqual(file.data, 'yz\n');
  }));
}

assert.throws(
  () => {
    fs.createReadStream(rangeFile, { start: 10, end: 2 });
  },
  {
    code: 'ERR_OUT_OF_RANGE',
    message: 'The value of "start" is out of range. It must be <= "end"' +
             ' (here: 2). Received 10',
    name: 'RangeError'
  });

{
  const stream = fs.createReadStream(rangeFile, { start: 0, end: 0 });
  stream.data = '';

  stream.on('data', function(chunk) {
    stream.data += chunk;
  });

  stream.on('end', common.mustCall(function() {
    assert.strictEqual(stream.data, 'x');
  }));
}

{
  // Verify that end works when start is not specified.
  const stream = new fs.createReadStream(rangeFile, { end: 1 });
  stream.data = '';

  stream.on('data', function(chunk) {
    stream.data += chunk;
  });

  stream.on('end', common.mustCall(function() {
    assert.strictEqual(stream.data, 'xy');
  }));
}

if (!common.isWindows) {
  // Verify that end works when start is not specified, and we do not try to
  // use positioned reads. This makes sure that this keeps working for
  // non-seekable file descriptors.
  tmpdir.refresh();
  const filename = `${tmpdir.path}/foo.pipe`;
  const mkfifoResult = child_process.spawnSync('mkfifo', [filename]);
  if (!mkfifoResult.error) {
    child_process.exec(`echo "xyz foobar" > '${filename}'`);
    const stream = new fs.createReadStream(filename, { end: 1 });
    stream.data = '';

    stream.on('data', function(chunk) {
      stream.data += chunk;
    });

    stream.on('end', common.mustCall(function() {
      assert.strictEqual(stream.data, 'xy');
      fs.unlinkSync(filename);
    }));
  } else {
    common.printSkipMessage('mkfifo not available');
  }
}

{
  // Pause and then resume immediately.
  const pauseRes = fs.createReadStream(rangeFile);
  pauseRes.pause();
  pauseRes.resume();
}

{
  let file = fs.createReadStream(rangeFile, { autoClose: false });
  let data = '';
  file.on('data', function(chunk) { data += chunk; });
  file.on('end', common.mustCall(function() {
    assert.strictEqual(data, 'xyz\n');
    process.nextTick(function() {
      assert(!file.closed);
      assert(!file.destroyed);
      fileNext();
    });
  }));

  function fileNext() {
    // This will tell us if the fd is usable again or not.
    file = fs.createReadStream(null, { fd: file.fd, start: 0 });
    file.data = '';
    file.on('data', function(data) {
      file.data += data;
    });
    file.on('end', common.mustCall(function(err) {
      assert.strictEqual(file.data, 'xyz\n');
    }));
    process.on('exit', function() {
      assert(file.closed);
      assert(file.destroyed);
    });
  }
}

{
  // Just to make sure autoClose won't close the stream because of error.
  const file = fs.createReadStream(null, { fd: 13337, autoClose: false });
  file.on('data', common.mustNotCall());
  file.on('error', common.mustCall());
  process.on('exit', function() {
    assert(!file.closed);
    assert(!file.destroyed);
    assert(file.fd);
  });
}

{
  // Make sure stream is destroyed when file does not exist.
  const file = fs.createReadStream('/path/to/file/that/does/not/exist');
  file.on('data', common.mustNotCall());
  file.on('error', common.mustCall());

  process.on('exit', function() {
    assert(!file.closed);
    assert(file.destroyed);
  });
}
