import { denoErrorToNodeError } from "../internal/errors.ts";
export type statOptions = { bigint: boolean; throwIfNoEntry?: boolean;};
export type Stats = { dev: number | null; ino: number | null; mode: number | null; nlink: number | null; uid: number | null; gid: number | null; rdev: number | null; size: number; blksize: number | null; blocks: number | null; mtime: Date | null; atime: Date | null; birthtime: Date | null; ctime: Date | null; atimeMs: number | null; mtimeMs: number | null; ctimeMs: number | null; birthtimeMs: number | null; isBlockDevice: () => boolean; isCharacterDevice: () => boolean; isDirectory: () => boolean; isFIFO: () => boolean; isFile: () => boolean; isSocket: () => boolean; isSymbolicLink: () => boolean;};
export type BigIntStats = { dev: BigInt | null; ino: BigInt | null; mode: BigInt | null; nlink: BigInt | null; uid: BigInt | null; gid: BigInt | null; rdev: BigInt | null; size: BigInt; blksize: BigInt | null; blocks: BigInt | null; mtime: Date | null; atime: Date | null; birthtime: Date | null; ctime: Date | null; atimeMs: BigInt | null; mtimeMs: BigInt | null; ctimeMs: BigInt | null; birthtimeMs: BigInt | null; atimeNs: BigInt | null; mtimeNs: BigInt | null; ctimeNs: BigInt | null; birthtimeNs: BigInt | null; isBlockDevice: () => boolean; isCharacterDevice: () => boolean; isDirectory: () => boolean; isFIFO: () => boolean; isFile: () => boolean; isSocket: () => boolean; isSymbolicLink: () => boolean;};
export function convertFileInfoToStats(origin: Deno.FileInfo): Stats { return { dev: origin.dev, ino: origin.ino, mode: origin.mode, nlink: origin.nlink, uid: origin.uid, gid: origin.gid, rdev: origin.rdev, size: origin.size, blksize: origin.blksize, blocks: origin.blocks, mtime: origin.mtime, atime: origin.atime, birthtime: origin.birthtime, mtimeMs: origin.mtime?.getTime() || null, atimeMs: origin.atime?.getTime() || null, birthtimeMs: origin.birthtime?.getTime() || null, isFile: () => origin.isFile, isDirectory: () => origin.isDirectory, isSymbolicLink: () => origin.isSymlink, isBlockDevice: () => false, isFIFO: () => false, isCharacterDevice: () => false, isSocket: () => false, ctime: origin.mtime, ctimeMs: origin.mtime?.getTime() || null, };}
function toBigInt(number?: number | null) { if (number === null || number === undefined) return null; return BigInt(number);}
export function convertFileInfoToBigIntStats( origin: Deno.FileInfo,): BigIntStats { return { dev: toBigInt(origin.dev), ino: toBigInt(origin.ino), mode: toBigInt(origin.mode), nlink: toBigInt(origin.nlink), uid: toBigInt(origin.uid), gid: toBigInt(origin.gid), rdev: toBigInt(origin.rdev), size: toBigInt(origin.size) || 0n, blksize: toBigInt(origin.blksize), blocks: toBigInt(origin.blocks), mtime: origin.mtime, atime: origin.atime, birthtime: origin.birthtime, mtimeMs: origin.mtime ? BigInt(origin.mtime.getTime()) : null, atimeMs: origin.atime ? BigInt(origin.atime.getTime()) : null, birthtimeMs: origin.birthtime ? BigInt(origin.birthtime.getTime()) : null, mtimeNs: origin.mtime ? BigInt(origin.mtime.getTime()) * 1000000n : null, atimeNs: origin.atime ? BigInt(origin.atime.getTime()) * 1000000n : null, birthtimeNs: origin.birthtime ? BigInt(origin.birthtime.getTime()) * 1000000n : null, isFile: () => origin.isFile, isDirectory: () => origin.isDirectory, isSymbolicLink: () => origin.isSymlink, isBlockDevice: () => false, isFIFO: () => false, isCharacterDevice: () => false, isSocket: () => false, ctime: origin.mtime, ctimeMs: origin.mtime ? BigInt(origin.mtime.getTime()) : null, ctimeNs: origin.mtime ? BigInt(origin.mtime.getTime()) * 1000000n : null, };}
export function CFISBIS(fileInfo: Deno.FileInfo, bigInt: boolean) { if (bigInt) return convertFileInfoToBigIntStats(fileInfo); return convertFileInfoToStats(fileInfo);}
export type statCallbackBigInt = (err: Error | null, stat: BigIntStats) => void;
export type statCallback = (err: Error | null, stat: Stats) => void;
export function stat(path: string | URL, callback: statCallback): void;export function stat( path: string | URL, options: { bigint: false }, callback: statCallback,): void;export function stat( path: string | URL, options: { bigint: true }, callback: statCallbackBigInt,): void;export function stat( path: string | URL, optionsOrCallback: statCallback | statCallbackBigInt | statOptions, maybeCallback?: statCallback | statCallbackBigInt,) { const callback = (typeof optionsOrCallback === "function" ? optionsOrCallback : maybeCallback) as ( ...args: [Error] | [null, BigIntStats | Stats] ) => void; const options = typeof optionsOrCallback === "object" ? optionsOrCallback : { bigint: false };
if (!callback) throw new Error("No callback function supplied");
Deno.stat(path).then( (stat) => callback(null, CFISBIS(stat, options.bigint)), (err) => callback(denoErrorToNodeError(err, { syscall: "stat" })), );}
export function statSync(path: string | URL): Stats;export function statSync( path: string | URL, options: { bigint: false; throwIfNoEntry?: boolean },): Stats;export function statSync( path: string | URL, options: { bigint: true; throwIfNoEntry?: boolean },): BigIntStats;export function statSync( path: string | URL, options: statOptions = { bigint: false, throwIfNoEntry: true },): Stats | BigIntStats | undefined { try { const origin = Deno.statSync(path); return CFISBIS(origin, options.bigint); } catch (err) { if ( options?.throwIfNoEntry === false && err instanceof Deno.errors.NotFound ) { return; } if (err instanceof Error) { throw denoErrorToNodeError(err, { syscall: "stat" }); } else { throw err; } }}