orker_threads',
  'zlib',
]));

const warnedModules = new SafeSet();
function supportedInUserSnapshot(id) {
  return supportedModules.has(id);
}

function requireForUserSnapshot(id) {
  const normalizedId = normalizeRequirableId(id);
  if (!normalizedId) {
    // eslint-disable-next-line no-restricted-syntax
    const err = new Error(
      `Cannot find module '${id}'. `,
    );
    err.code = 'MODULE_NOT_FOUND';
    throw err;
  }
  if (!supportedInUserSnapshot(normalizedId)) {
    if (!warnedModules.has(normalizedId)) {
      process.emitWarning(
        `built-in module ${id} is not yet supported in user snapshots`);
      warnedModules.add(normalizedId);
    }
  }

  return require(normalizedId);
}

function main() {
  const {
    prepareMainThreadExecution,
  } = require('internal/process/pre_execution');

  prepareMainThreadExecution(true, false);

  const file = process.argv[1];
  const path = require('path');
  const filename = path.resolve(file);
  const dirname = path.dirname(filename);
  const source = readFileSync(file, 'utf-8');
  const serializeMainFunction = compileSerializeMain(filename, source);

  const {
    initializeCallbacks,
    namespace: {
      addSerializeCallback,
      addDeserializeCallback,
    },
  } = require('internal/v8/startup_snapshot');
  initializeCallbacks();

  let stackTraceLimitDesc;
  addDeserializeCallback(() => {
    if (stackTraceLimitDesc !== undefined) {
      ObjectDefineProperty(Error, 'stackTraceLimit', stackTraceLimitDesc);
    }
  });

  if (getOptionValue('--inspect-brk')) {
    internalBinding('inspector').callAndPauseOnStart(
      serializeMainFunction, undefined,
      requireForUserSnapshot, filename, dirname);
  } else {
    serializeMainFunction(requireForUserSnapshot, filename, dirname);
  }

  addSerializeCallback(() => {
    stackTraceLimitDesc = ObjectGetOwnPropertyDescriptor(Error, 'stackTraceLimit');

    if (stackTraceLimitDesc !== undefined) {
      // We want to use null-prototype objects to not rely on globally mutable
      // %Object.prototype%.
      ObjectSetPrototypeOf(stackTraceLimitDesc, null);
      process._rawDebug('Deleting Error.stackTraceLimit from the snapshot. ' +
                        'It will be re-installed after deserialization');
      delete Error.stackTraceLimit;
    }
  });
}

main();
