import { FsManager, FileName } from "./lib/fm/index.js"

import { Filesystem, Path, Stat } from "./lib/filesystem/index.js"

let fm = new FsManager

let fsM = new Filesystem

export async function readFile(name) {
  let i = new FileName()
  i.setFilepath(name)
  i.setType("file")

  let content = []
  try {
    await fm.GetFile(i, (fd) => {
      content.push(Buffer.from(fd.getData()))
    })
  } catch(e) {
    throw e
  }
  return Buffer.concat(content)
}



const  ModeDir        = 0x80000000; // d: is a directory
const  ModeAppend     = 0x40000000; // a: append-only
const  ModeExclusive  = 0x20000000; // l: exclusive use
const  ModeTemporary  = 0x10000000; // T: temporary file; Plan 9 only
const  ModeSymlink    = 0x8000000;  // L: symbolic link
const  ModeDevice     = 0x4000000;  // D: device file
const  ModeNamedPipe  = 0x2000000;  // p: named pipe (FIFO)
const  ModeSocket     = 0x1000000;  // S: Unix domain socket
const  ModeSetuid     = 0x800000;   // u: setuid
const  ModeSetgid     = 0x400000;   // g: setgid
const  ModeCharDevice = 0x200000;   // c: Unix character device, when ModeDevice is set
const  ModeSticky     = 0x100000;   // t: sticky
const  ModeIrregular  = 0x8f280000; // ?: non-regular file; nothing else is known about this file
  // Mask for the type bits. For regular files, none will be set.
const  ModeType = ModeDir | ModeSymlink | ModeNamedPipe | ModeSocket | ModeDevice | ModeCharDevice | ModeIrregular;
const  ModePerm = 0o777; // Unix permission bits


// modeled on the nodejs' fs.Stats
export class Stats {
  constructor(raw) {
    const mtime = raw.modtime
    this.mtimeMS = this.ctimeMS = Date.parse(mtime);
    this.mtime = this.ctime = mtime;

    const now = new Date();
    this.atimeMS = now.getTime();
    this.atime = now.toUTCString();

    this.mode = raw.mode;

    this.size = raw.size;

    // doesn't support now.
    this.dev =
      this.rdev =
      this.blksize =
      this.blocks =
      this.ino =
      this.nlink =
      this.uid =
      this.gid = -1;
  }

  isDirectory() { return (this.mode&ModeDir) != 0 }
  isFIFO() { return (this.mode&ModeNamedPipe) != 0 }
  isFile() { return (this.mode&ModeType) == 0 }
  isSocket() { return (this.mode&ModeSocket) != 0 }
  isSymbolicLink() { return (this.mode&ModeSymlink) != 0 }
}

export async function stat(path) {
  let p = new Path();
  p.setPath(path);
  return new Stats((await fsM.Stat(p)).toObject())
}
