/**
 * @license
 * Copyright 2018 The Emscripten Authors
 * SPDX-License-Identifier: MIT
 */

addToLibrary({
  $NODERAWFS__deps: ['$ERRNO_CODES', '$FS', '$NODEFS', '$mmapAlloc', '$FS_modeStringToFlags', '$NODERAWFS_stream_funcs'],
  $NODERAWFS__postset: `
    if (!ENVIRONMENT_IS_NODE) {
      throw new Error('NODERAWFS is currently only supported on Node.js environment.')
    }
    var nodeTTY = require('node:tty');
    function _wrapNodeError(func) {
      return (...args) => {
        try {
          return func(...args)
        } catch (e) {
          // Hack for Deno which throws BadResource instead of EBADF:
          // https://github.com/emscripten-core/emscripten/issues/26239
          if (e.name == 'BadResource') {
            e.code = 'EBADF';
          }
          if (e.code) {
            throw new FS.ErrnoError(ERRNO_CODES[e.code]);
          }
          throw e;
        }
      }
    }
    function _wrapNodeStreamFunc(func, vfs_func) {
      return _wrapNodeError((stream, ...args) => {
        if (stream.stream_ops) {
          // this stream was created by some other FS. e.g: PIPEFS.
          return vfs_func(stream, ...args);
        }
        return func(stream, ...args);
      });
    }
    // Use this to reference our in-memory filesystem
    /** @suppress {partialAlias} */
    var VFS = {...FS};
    // Wrap the whole in-memory filesystem API with
    // our Node.js based functions
    for (const [key, value] of Object.entries(NODERAWFS)) {
      FS[key] = _wrapNodeError(value);
    }
    for (const [key, value] of Object.entries(NODERAWFS_stream_funcs)) {
      FS[key] = _wrapNodeStreamFunc(value, FS[key]);
    }`,
  $NODERAWFS: {
    lookup(parent, name) {
#if ASSERTIONS
      assert(parent)
      assert(parent.path)
#endif
      return FS.lookupPath(`${parent.path}/${name}`).node;
    },
    lookupPath(path, opts = {}) {
      if (opts.parent) {
        path = PATH.dirname(path);
      }
      var st = fs.lstatSync(path);
      var mode = NODEFS.getMode(path);
      return { path, node: { id: st.ino, mode, node_ops: NODERAWFS, path }};
    },
    createStandardStreams() {
      FS.createStream({ nfd: 0, position: 0, path: '/dev/stdin', flags: 0, seekable: false }, 0);
      var paths = [,'/dev/stdout', '/dev/stderr'];
      for (var i = 1; i < 3; i++) {
        FS.createStream({ nfd: i, position: 0, path: paths[i], flags: {{{ cDefs.O_TRUNC | cDefs.O_CREAT | cDefs.O_WRONLY }}}, seekable: false }, i);
      }
    },
    // generic function for all node creation
    cwd() { return process.cwd(); },
    chdir(...args) { process.chdir(...args); },
    mknod(path, mode) {
      if (FS.isDir(path)) {
        fs.mkdirSync(path, mode);
      } else {
        fs.writeFileSync(path, '', { mode: mode });
      }
    },
    mkdir(...args) { fs.mkdirSync(...args); },
    symlink(...args) { fs.symlinkSync(...args); },
    link(oldpath, newpath, flags) {
      // AT_SYMLINK_FOLLOW (0x400): dereference oldpath if it is a symlink,
      // since node's link(2) links to the symlink itself by default.
      if (flags & 0x400) {
        oldpath = fs.realpathSync(oldpath);
      }
      fs.linkSync(oldpath, newpath);
    },
    rename(...args) { fs.renameSync(...args); },
    rmdir(...args) { fs.rmdirSync(...args); },
    readdir(...args) { return ['.', '..'].concat(fs.readdirSync(...args)); },
    unlink(...args) { fs.unlinkSync(...args); },
    readlink(...args) { return fs.readlinkSync(...args); },
    stat(path, dontFollow) {
      var stat = dontFollow ? fs.lstatSync(path) : fs.statSync(path);
      if (NODEFS.isWindows) {
        // Windows does not report the 'x' permission bit, so propagate read
        // bits to execute bits.
        stat.mode |= (stat.mode & {{{ cDefs.S_IRUGO }}}) >> 2;
      }
      return stat;
    },
    fstat(fd) {
      var stream = FS.getStreamChecked(fd);
      // Virtual streams (pipes, sockets) have no backing node fd; defer to their
      // own getattr rather than node's fs.fstatSync.
      var getattr = stream.stream_ops?.getattr ?? stream.node.node_ops?.getattr;
      if (getattr) {
        return getattr(stream.stream_ops?.getattr ? stream : stream.node);
      }
      return fs.fstatSync(stream.nfd);
    },
    statfs(path) {
      // Node's fs.statfsSync API doesn't provide these attributes so include
      // some defaults.
      var defaults = {
        fsid: 42,
        flags: 2,
        namelen: 255,
      }
      return Object.assign(defaults, fs.statfsSync(path));
    },
    statfsStream(stream) {
      return FS.statfs(stream.path);
    },
    chmod(path, mode, dontFollow) {
      mode &= {{{ cDefs.S_IALLUGO }}};
      if (NODEFS.isWindows) {
        // Windows only supports S_IREAD / S_IWRITE (S_IRUSR / S_IWUSR)
        // https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/chmod-wchmod
        mode &= {{{ cDefs.S_IRUSR | cDefs.S_IWUSR }}};
      }
      if (dontFollow && fs.lstatSync(path).isSymbolicLink()) {
        // Node (and indeed linux) does not support chmod on symlinks
        // https://nodejs.org/api/fs.html#fslchmodsyncpath-mode
        throw new FS.ErrnoError({{{ cDefs.EOPNOTSUPP }}});
      }
      fs.chmodSync(path, mode);
    },
    fchmod(fd, mode) {
      var stream = FS.getStreamChecked(fd);
      fs.fchmodSync(stream.nfd, mode);
    },
    chown(...args) { fs.chownSync(...args); },
    fchown(fd, owner, group) {
      var stream = FS.getStreamChecked(fd);
      fs.fchownSync(stream.nfd, owner, group);
    },
    truncate(path, len) {
      // See https://github.com/nodejs/node/issues/35632
      if (len < 0) {
        throw new FS.ErrnoError({{{ cDefs.EINVAL }}});
      }
      return fs.truncateSync(path, len);
    },
    ftruncate(fd, len) {
      // See https://github.com/nodejs/node/issues/35632
      if (len < 0) {
        throw new FS.ErrnoError({{{ cDefs.EINVAL }}});
      }
      var stream = FS.getStreamChecked(fd);
      fs.ftruncateSync(stream.nfd, len);
    },
    utime(path, atime, mtime, dontFollow) {
      // null here for atime or mtime means UTIME_OMIT was passed.  Since node
      // doesn't support this concept we need to first find the existing
      // timestamps in order to preserve them.
      if ((atime === null) || (mtime === null)) {
        var st = dontFollow ? fs.lstatSync(path) : fs.statSync(path);
        atime ||= st.atimeMs;
        mtime ||= st.mtimeMs;
      }
      if (dontFollow) {
        fs.lutimesSync(path, atime/1000, mtime/1000);
      } else {
        fs.utimesSync(path, atime/1000, mtime/1000);
      }
    },
    open(path, flags, mode) {
      flags = FS_modeStringToFlags(flags);
      var pathTruncated = path.split('/').map((s) => s.slice(0, 255)).join('/');
      var nfd = fs.openSync(pathTruncated, NODEFS.flagsForNode(flags), mode);
      var st = fs.fstatSync(nfd);
      if (flags & {{{ cDefs.O_DIRECTORY }}} && !st.isDirectory()) {
        fs.closeSync(nfd);
        throw new FS.ErrnoError(ERRNO_CODES.ENOTDIR);
      }
      var newMode = NODEFS.getMode(pathTruncated);
      var node = { id: st.ino, mode: newMode, node_ops: NODERAWFS, path }
      return FS.createStream({ nfd, position: 0, path, flags, node, seekable: true });
    },
    createStream(stream, fd) {
      // Call the original FS.createStream
      var rtn = VFS.createStream(stream, fd);
      // Detect PIPEFS streams and skip the refcnt/tty initialization in that case.
      if (!stream.stream_ops) {
        rtn.shared.refcnt ??= 0;
        rtn.shared.refcnt++;
        rtn.tty = nodeTTY.isatty(rtn.nfd);
      }
      return rtn;
    },
  },

  /**
   * These functions all take a stream as the first argument which
   * could either be a stream created by NODERAWFS itself, or, for example
   * one created by PIPEFS.  We wrap all these function in an extra check.
   */
  $NODERAWFS_stream_funcs: {
    close(stream) {
      VFS.closeStream(stream.fd);
      // Don't close stdin/stdout/stderr since they are used by node itself.
      if (--stream.shared.refcnt <= 0 && stream.nfd > 2) {
        // This stream is created by our Node.js filesystem, close the
        // native file descriptor when its reference count drops to 0.
        fs.closeSync(stream.nfd);
      }
    },
    llseek(stream, offset, whence) {
      var position = offset;
      if (whence === {{{ cDefs.SEEK_CUR }}}) {
        position += stream.position;
      } else if (whence === {{{ cDefs.SEEK_END }}}) {
        position += fs.fstatSync(stream.nfd).size;
      } else if (whence !== {{{ cDefs.SEEK_SET }}}) {
        throw new FS.ErrnoError({{{ cDefs.EINVAL }}});
      }

      if (position < 0) {
        throw new FS.ErrnoError({{{ cDefs.EINVAL }}});
      }
      stream.position = position;
      return position;
    },
    read(stream, buffer, offset, length, position) {
      var seeking = typeof position != 'undefined';
      if (!seeking && stream.seekable) position = stream.position;
      var bytesRead = fs.readSync(stream.nfd, buffer, offset, length, position);
      // update position marker when non-seeking
      if (!seeking) stream.position += bytesRead;
      return bytesRead;
    },
    write(stream, buffer, offset, length, position) {
      if (stream.flags & {{{ cDefs.O_APPEND }}}) {
        // seek to the end before writing in append mode
        FS.llseek(stream, 0, {{{ cDefs.SEEK_END }}});
      }
      var seeking = typeof position != 'undefined';
      if (!seeking && stream.seekable) position = stream.position;
      var bytesWritten = fs.writeSync(stream.nfd, buffer, offset, length, position);
      // update position marker when non-seeking
      if (!seeking) stream.position += bytesWritten;
      return bytesWritten;
    },
    mmap(stream, length, position, prot, flags) {
      if (!length) {
        throw new FS.ErrnoError({{{ cDefs.EINVAL }}});
      }
      var ptr = mmapAlloc(length);
      FS.read(stream, HEAP8, ptr, length, position);
      return { ptr, allocated: true };
    },
    msync(stream, buffer, offset, length, mmapFlags) {
      FS.write(stream, buffer, 0, length, offset);
      // should we check if bytesWritten and length are the same?
      return 0;
    },
    ioctl(stream, cmd, arg) {
      throw new FS.ErrnoError({{{ cDefs.ENOTTY }}});
    },
  },
});
