'use strict';

// Flags: --experimental-vm-modules

const common = require('../common');
const assert = require('assert');
const {
  Module,
  SourceTextModule,
  SyntheticModule,
  createContext,
  compileFunction,
} = require('vm');
const util = require('util');

(async function test1() {
  const context = createContext({
    foo: 'bar',
    baz: undefined,
    typeofProcess: undefined,
  });
  const m = new SourceTextModule(
    'baz = foo; typeofProcess = typeof process; typeof Object;',
    { context }
  );
  assert.strictEqual(m.status, 'unlinked');
  await m.link(common.mustNotCall());
  assert.strictEqual(m.status, 'linked');
  assert.strictEqual(await m.evaluate(), undefined);
  assert.strictEqual(m.status, 'evaluated');
  assert.deepStrictEqual(context, {
    foo: 'bar',
    baz: 'bar',
    typeofProcess: 'undefined'
  });
}().then(common.mustCall()));

(async () => {
  const m = new SourceTextModule(`
    global.vmResultFoo = "foo";
    global.vmResultTypeofProcess = Object.prototype.toString.call(process);
  `);
  await m.link(common.mustNotCall());
  await m.evaluate();
  assert.strictEqual(global.vmResultFoo, 'foo');
  assert.strictEqual(global.vmResultTypeofProcess, '[object process]');
  delete global.vmResultFoo;
  delete global.vmResultTypeofProcess;
})().then(common.mustCall());

(async () => {
  const m = new SourceTextModule('while (true) {}');
  await m.link(common.mustNotCall());
  await m.evaluate({ timeout: 500 })
    .then(() => assert(false), () => {});
})().then(common.mustCall());

// Check the generated identifier for each module
(async () => {
  const context1 = createContext({ });
  const context2 = createContext({ });

  const m1 = new SourceTextModule('1', { context: context1 });
  assert.strictEqual(m1.identifier, 'vm:module(0)');
  const m2 = new SourceTextModule('2', { context: context1 });
  assert.strictEqual(m2.identifier, 'vm:module(1)');
  const m3 = new SourceTextModule('3', { context: context2 });
  assert.strictEqual(m3.identifier, 'vm:module(0)');
})().then(common.mustCall());

// Check inspection of the instance
{
  const context = createContext({ foo: 'bar' });
  const m = new SourceTextModule('1', { context });

  assert.strictEqual(
    util.inspect(m),
    `SourceTextModule {
  status: 'unlinked',
  identifier: 'vm:module(0)',
  context: { foo: 'bar' }
}`
  );

  assert.strictEqual(util.inspect(m, { depth: -1 }), '[SourceTextModule]');

  assert.throws(
    () => m[util.inspect.custom].call(Object.create(null)),
    {
      code: 'ERR_VM_MODULE_NOT_MODULE',
      message: 'Provided module is not an instance of Module'
    },
  );
}

{
  const context = createContext({ foo: 'bar' });
  const m = new SyntheticModule([], () => {}, { context });

  assert.strictEqual(
    util.inspect(m),
    `SyntheticModule {
  status: 'unlinked',
  identifier: 'vm:module(0)',
  context: { foo: 'bar' }
}`
  );

  assert.strictEqual(util.inspect(m, { depth: -1 }), '[SyntheticModule]');
}

// Check dependencies getter returns same object every time
{
  const m = new SourceTextModule('');
  const dep = m.dependencySpecifiers;
  assert.notStrictEqual(dep, undefined);
  assert.strictEqual(dep, m.dependencySpecifiers);
}

// Check the impossibility of creating an abstract instance of the Module.
{
  assert.throws(() => new Module(), {
    message: 'Module is not a constructor',
    name: 'TypeError'
  });
}

// Check to throws invalid exportNames
{
  assert.throws(() => new SyntheticModule(undefined, () => {}, {}), {
    message: 'The "exportNames" argument must be an ' +
        'Array of unique strings.' +
        ' Received undefined',
    name: 'TypeError'
  });
}

// Check to throws duplicated exportNames
// https://github.com/nodejs/node/issues/32806
{
  assert.throws(() => new SyntheticModule(['x', 'x'], () => {}, {}), {
    message: 'The property \'exportNames.x\' is duplicated. Received \'x\'',
    name: 'TypeError',
  });
}

// Check to throws invalid evaluateCallback
{
  assert.throws(() => new SyntheticModule([], undefined, {}), {
    message: 'The "evaluateCallback" argument must be of type function.' +
      ' Received undefined',
    name: 'TypeError'
  });
}

// Check to throws invalid options
{
  assert.throws(() => new SyntheticModule([], () => {}, null), {
    message: 'The "options" argument must be of type object.' +
      ' Received null',
    name: 'TypeError'
  });
}

// Test compileFunction importModuleDynamically
{
  const module = new SyntheticModule([], () => {});
  module.link(() => {});
  const f = compileFunction('return import("x")', [], {
    importModuleDynamically(specifier, referrer) {
      assert.strictEqual(specifier, 'x');
      assert.strictEqual(referrer, f);
      return module;
    },
  });
  f().then((ns) => {
    assert.strictEqual(ns, module.namespace);
  });
}
