import assert from "node:assert";
import { describe, it } from "node:test";
import { convertDocument, detectFormatFromContent, detectFormatFromExtension, generateOutputPath, parseContent, serializeContent, } from "./file-format.js";
describe("File Format Utilities", () => {
    describe("detectFormatFromExtension", () => {
        it("should detect JSON format from .json extension", () => {
            assert.strictEqual(detectFormatFromExtension("api.json"), "json");
            assert.strictEqual(detectFormatFromExtension("/path/to/openapi.json"), "json");
            assert.strictEqual(detectFormatFromExtension("FILE.JSON"), "json");
        });
        it("should detect YAML format from .yaml extension", () => {
            assert.strictEqual(detectFormatFromExtension("api.yaml"), "yaml");
            assert.strictEqual(detectFormatFromExtension("/path/to/openapi.yaml"), "yaml");
            assert.strictEqual(detectFormatFromExtension("FILE.YAML"), "yaml");
        });
        it("should detect YAML format from .yml extension", () => {
            assert.strictEqual(detectFormatFromExtension("api.yml"), "yaml");
            assert.strictEqual(detectFormatFromExtension("/path/to/openapi.yml"), "yaml");
            assert.strictEqual(detectFormatFromExtension("FILE.YML"), "yaml");
        });
        it("should return null for unknown extensions", () => {
            assert.strictEqual(detectFormatFromExtension("api.txt"), null);
            assert.strictEqual(detectFormatFromExtension("api"), null);
            assert.strictEqual(detectFormatFromExtension("api.xml"), null);
        });
    });
    describe("detectFormatFromContent", () => {
        it("should detect JSON content", () => {
            const content = '{"openapi": "3.1.0"}';
            assert.strictEqual(detectFormatFromContent(content), "json");
        });
        it("should detect YAML content", () => {
            const content = "openapi: 3.1.0\ninfo:\n  title: Test";
            assert.strictEqual(detectFormatFromContent(content), "yaml");
        });
        it("should throw error for invalid content", () => {
            const content = "not valid json or yaml: : :";
            assert.throws(() => detectFormatFromContent(content), /Failed to parse content/);
        });
    });
    describe("parseContent", () => {
        it("should parse JSON content", () => {
            const content = '{"openapi": "3.1.0", "info": {"title": "Test"}}';
            const result = parseContent(content, "json");
            assert.deepStrictEqual(result, {
                openapi: "3.1.0",
                info: { title: "Test" },
            });
        });
        it("should parse YAML content", () => {
            const content = `openapi: 3.1.0
info:
  title: Test
  version: 1.0.0`;
            const result = parseContent(content, "yaml");
            assert.deepStrictEqual(result, {
                openapi: "3.1.0",
                info: { title: "Test", version: "1.0.0" },
            });
        });
        it("should throw error for invalid JSON", () => {
            const content = "{invalid json}";
            assert.throws(() => parseContent(content, "json"), {
                name: "SyntaxError",
            });
        });
        it("should throw error for invalid YAML", () => {
            const content = ":\ninvalid: : yaml";
            assert.throws(() => parseContent(content, "yaml"));
        });
        it("should handle arrays", () => {
            const jsonContent = "[1, 2, 3]";
            const yamlContent = "- 1\n- 2\n- 3";
            assert.deepStrictEqual(parseContent(jsonContent, "json"), [1, 2, 3]);
            assert.deepStrictEqual(parseContent(yamlContent, "yaml"), [1, 2, 3]);
        });
        it("should handle nested structures", () => {
            const content = {
                openapi: "3.1.0",
                paths: {
                    "/users": {
                        get: {
                            summary: "Get users",
                            parameters: [{ name: "limit", in: "query" }],
                        },
                    },
                },
            };
            const jsonContent = JSON.stringify(content);
            const result = parseContent(jsonContent, "json");
            assert.deepStrictEqual(result, content);
        });
    });
    describe("serializeContent", () => {
        const testDocument = {
            openapi: "3.1.0",
            info: {
                title: "Test API",
                version: "1.0.0",
            },
        };
        it("should serialize to JSON with proper formatting", () => {
            const result = serializeContent(testDocument, "json");
            assert.strictEqual(typeof result, "string");
            assert.strictEqual(result.includes('"openapi": "3.1.0"'), true);
            assert.strictEqual(result.includes('"title": "Test API"'), true);
            assert.strictEqual(result.endsWith("\n"), true);
            // Verify it's valid JSON
            const parsed = JSON.parse(result);
            assert.deepStrictEqual(parsed, testDocument);
        });
        it("should serialize to YAML with proper formatting", () => {
            const result = serializeContent(testDocument, "yaml");
            assert.strictEqual(typeof result, "string");
            assert.strictEqual(result.includes("openapi: 3.1.0"), true);
            assert.strictEqual(result.includes("title: Test API"), true);
            assert.strictEqual(result.includes("version: 1.0.0"), true);
        });
        it("should handle arrays in JSON", () => {
            const doc = { items: [1, 2, 3] };
            const result = serializeContent(doc, "json");
            assert.strictEqual(result.includes('"items": [\n'), true);
            const parsed = JSON.parse(result);
            assert.deepStrictEqual(parsed, doc);
        });
        it("should handle arrays in YAML", () => {
            const doc = { items: [1, 2, 3] };
            const result = serializeContent(doc, "yaml");
            assert.strictEqual(result.includes("items:"), true);
            assert.strictEqual(result.includes("- 1"), true);
        });
        it("should handle special characters in YAML", () => {
            const doc = {
                description: 'This has a colon: and quotes "test"',
            };
            const result = serializeContent(doc, "yaml");
            assert.strictEqual(typeof result, "string");
            // Should be properly escaped
            assert.strictEqual(result.includes("description:"), true);
        });
        it("should handle null values", () => {
            const doc = { value: null };
            const jsonResult = serializeContent(doc, "json");
            const yamlResult = serializeContent(doc, "yaml");
            assert.strictEqual(jsonResult.includes('"value": null'), true);
            assert.strictEqual(yamlResult.includes("value:"), true);
        });
    });
    describe("convertDocument", () => {
        const testDocument = {
            openapi: "3.1.0",
            info: {
                title: "Test API",
                version: "1.0.0",
            },
            paths: {},
        };
        it("should convert from JSON to YAML", () => {
            const jsonContent = JSON.stringify(testDocument);
            const result = convertDocument(jsonContent, "json", "yaml");
            assert.strictEqual(result.format, "yaml");
            assert.strictEqual(typeof result.content, "string");
            assert.strictEqual(result.content.includes("openapi: 3.1.0"), true);
            assert.strictEqual(result.content.includes("title: Test API"), true);
        });
        it("should convert from YAML to JSON", () => {
            const yamlContent = `openapi: 3.1.0
info:
  title: Test API
  version: 1.0.0
paths: {}`;
            const result = convertDocument(yamlContent, "yaml", "json");
            assert.strictEqual(result.format, "json");
            assert.strictEqual(typeof result.content, "string");
            const parsed = JSON.parse(result.content);
            assert.strictEqual(parsed.openapi, "3.1.0");
            assert.strictEqual(parsed.info.title, "Test API");
        });
        it("should preserve data through JSON to YAML to JSON conversion", () => {
            const originalJson = JSON.stringify(testDocument);
            // JSON -> YAML
            const yamlResult = convertDocument(originalJson, "json", "yaml");
            // YAML -> JSON
            const jsonResult = convertDocument(yamlResult.content, "yaml", "json");
            const finalDocument = JSON.parse(jsonResult.content);
            assert.deepStrictEqual(finalDocument, testDocument);
        });
        it("should preserve data through YAML to JSON to YAML conversion", () => {
            const originalYaml = `openapi: 3.1.0
info:
  title: Test API
  version: 1.0.0
paths: {}`;
            // Parse original to compare
            const originalDoc = parseContent(originalYaml, "yaml");
            // YAML -> JSON
            const jsonResult = convertDocument(originalYaml, "yaml", "json");
            // JSON -> YAML
            const yamlResult = convertDocument(jsonResult.content, "json", "yaml");
            const finalDocument = parseContent(yamlResult.content, "yaml");
            assert.deepStrictEqual(finalDocument, originalDoc);
        });
        it("should handle complex nested structures", () => {
            const complexDoc = {
                openapi: "3.1.0",
                paths: {
                    "/users/{id}": {
                        get: {
                            parameters: [
                                { name: "id", in: "path", required: true },
                                { name: "fields", in: "query", required: false },
                            ],
                            responses: {
                                "200": {
                                    description: "Success",
                                    content: {
                                        "application/json": {
                                            schema: {
                                                type: "object",
                                                properties: {
                                                    id: { type: "string" },
                                                    name: { type: "string" },
                                                },
                                            },
                                        },
                                    },
                                },
                            },
                        },
                    },
                },
            };
            const jsonContent = JSON.stringify(complexDoc);
            const yamlResult = convertDocument(jsonContent, "json", "yaml");
            const backToJson = convertDocument(yamlResult.content, "yaml", "json");
            const finalDoc = JSON.parse(backToJson.content);
            assert.deepStrictEqual(finalDoc, complexDoc);
        });
        it("should handle empty objects and arrays", () => {
            const doc = {
                empty_object: {},
                empty_array: [],
                nested: {
                    also_empty: {},
                },
            };
            const jsonContent = JSON.stringify(doc);
            const yamlResult = convertDocument(jsonContent, "json", "yaml");
            const backToJson = convertDocument(yamlResult.content, "yaml", "json");
            const finalDoc = JSON.parse(backToJson.content);
            assert.deepStrictEqual(finalDoc, doc);
        });
    });
    describe("generateOutputPath", () => {
        it("should replace .json with .yaml", () => {
            assert.strictEqual(generateOutputPath("api.json", "yaml"), "api.yaml");
        });
        it("should replace .yaml with .json", () => {
            assert.strictEqual(generateOutputPath("api.yaml", "json"), "api.json");
        });
        it("should replace .yml with .json", () => {
            assert.strictEqual(generateOutputPath("api.yml", "json"), "api.json");
        });
        it("should handle paths with directories", () => {
            assert.strictEqual(generateOutputPath("/path/to/api.json", "yaml"), "/path/to/api.yaml");
            assert.strictEqual(generateOutputPath("/path/to/api.yaml", "json"), "/path/to/api.json");
        });
        it("should handle relative paths", () => {
            assert.strictEqual(generateOutputPath("./docs/api.json", "yaml"), "./docs/api.yaml");
            assert.strictEqual(generateOutputPath("../specs/api.yaml", "json"), "../specs/api.json");
        });
        it("should handle files with multiple dots in name", () => {
            assert.strictEqual(generateOutputPath("api.v1.0.json", "yaml"), "api.v1.0.yaml");
            assert.strictEqual(generateOutputPath("my.api.spec.yaml", "json"), "my.api.spec.json");
        });
        it("should append extension if file has no extension", () => {
            assert.strictEqual(generateOutputPath("api", "json"), "api.json");
            assert.strictEqual(generateOutputPath("openapi", "yaml"), "openapi.yaml");
        });
        it("should handle Windows-style paths", () => {
            assert.strictEqual(generateOutputPath("C:\\Users\\docs\\api.json", "yaml"), "C:\\Users\\docs\\api.yaml");
        });
        it("should always use .yaml extension (not .yml) for yaml output", () => {
            assert.strictEqual(generateOutputPath("api.yml", "yaml"), "api.yaml");
            assert.strictEqual(generateOutputPath("api.json", "yaml"), "api.yaml");
        });
    });
});
//# sourceMappingURL=file-format.spec.js.map