/* @vitest-environment node */

import { describe, it, expect, vi, beforeEach, afterEach } from "vitest";

vi.mock("node:fs/promises", () => ({
	default: {
		access: vi.fn(),
	},
}));

import fs from "node:fs/promises";
import { ApiError } from "./errors.js";
import { isFsNotFoundError, mapStorageReadError } from "./storageErrors.js";

describe("lib/api/storageErrors", () => {
	const ORIGINAL = process.env.NAS_ROOT_PATH;

	beforeEach(() => {
		vi.clearAllMocks();
		process.env.NAS_ROOT_PATH = "/mnt/niederlassungen";
	});

	afterEach(() => {
		process.env.NAS_ROOT_PATH = ORIGINAL;
	});

	it("isFsNotFoundError detects ENOENT/ENOTDIR", () => {
		expect(isFsNotFoundError({ code: "ENOENT" })).toBe(true);
		expect(isFsNotFoundError({ code: "ENOTDIR" })).toBe(true);
		expect(isFsNotFoundError({ code: "EACCES" })).toBe(false);
		expect(isFsNotFoundError(null)).toBe(false);
	});

	it("maps ENOENT to 404 when NAS root is accessible", async () => {
		fs.access.mockResolvedValue(undefined);

		const err = Object.assign(new Error("nope"), { code: "ENOENT" });
		const apiErr = await mapStorageReadError(err, {
			details: { branch: "NL01" },
		});

		expect(apiErr).toBeInstanceOf(ApiError);
		expect(apiErr.status).toBe(404);
		expect(apiErr.code).toBe("FS_NOT_FOUND");
		expect(apiErr.details).toEqual({ branch: "NL01" });
	});

	it("maps ENOENT to 500 when NAS root is NOT accessible", async () => {
		fs.access.mockRejectedValue(new Error("no access"));

		const err = Object.assign(new Error("nope"), { code: "ENOENT" });
		const apiErr = await mapStorageReadError(err, {
			details: { branch: "NL01" },
		});

		expect(apiErr).toBeInstanceOf(ApiError);
		expect(apiErr.status).toBe(500);
		expect(apiErr.code).toBe("FS_STORAGE_ERROR");
	});

	it("maps non-notfound filesystem errors to 500", async () => {
		fs.access.mockResolvedValue(undefined);

		const err = Object.assign(new Error("boom"), { code: "EACCES" });
		const apiErr = await mapStorageReadError(err, { details: { x: 1 } });

		expect(apiErr).toBeInstanceOf(ApiError);
		expect(apiErr.status).toBe(500);
		expect(apiErr.code).toBe("FS_STORAGE_ERROR");
	});
});
