//
//  ConversationNotesServiceTests.swift
//  oAITests
//
// SPDX-License-Identifier: PolyForm-Noncommercial-1.0.0
// Copyright (C) 2026 Rune Olsen

import Testing
import Foundation
@testable import Confab

@Suite("ConversationNotesService")
struct ConversationNotesServiceTests {

    @Test("makeFilename sanitizes the conversation name and appends a short ID suffix")
    func makeFilenameSanitizesAndSuffixes() {
        let id = UUID(uuidString: "A3F2B1C0-0000-0000-0000-000000000000")!
        let filename = ConversationNotesService.shared.makeFilename(conversationName: "My Recipe Chat", conversationId: id)
        #expect(filename == "My Recipe Chat-a3f2.md")
    }

    @Test("makeFilename sanitizes invalid filename characters in the conversation name")
    func makeFilenameSanitizesInvalidChars() {
        let id = UUID(uuidString: "A3F2B1C0-0000-0000-0000-000000000000")!
        let filename = ConversationNotesService.shared.makeFilename(conversationName: "Q&A: What/Why?", conversationId: id)
        #expect(filename == "Q&A- What-Why--a3f2.md")
    }

    @Test("makeFilename falls back to Untitled for an empty conversation name")
    func makeFilenameFallsBackForEmptyName() {
        let id = UUID(uuidString: "A3F2B1C0-0000-0000-0000-000000000000")!
        let filename = ConversationNotesService.shared.makeFilename(conversationName: "", conversationId: id)
        #expect(filename == "Untitled-a3f2.md")
    }

    @Test("write then readBody round-trips the body with the ID header stripped")
    func writeReadRoundTrip() {
        let id = UUID()
        let filename = "test-notes-\(UUID().uuidString).md"
        defer { ConversationNotesService.shared.delete(filename: filename) }

        ConversationNotesService.shared.write(body: "User prefers dark roast coffee.", filename: filename, conversationId: id)
        let body = ConversationNotesService.shared.readBody(filename: filename)

        #expect(body == "User prefers dark roast coffee.")
    }

    @Test("readBody on a nonexistent file returns nil, not an error")
    func readBodyMissingFileReturnsNil() {
        let body = ConversationNotesService.shared.readBody(filename: "definitely-does-not-exist-\(UUID().uuidString).md")
        #expect(body == nil)
    }

    @Test("readRaw returns the exact on-disk content, ID header included")
    func readRawIncludesHeader() {
        let id = UUID()
        let filename = "test-notes-\(UUID().uuidString).md"
        defer { ConversationNotesService.shared.delete(filename: filename) }

        ConversationNotesService.shared.write(body: "User prefers dark roast coffee.", filename: filename, conversationId: id)
        let raw = ConversationNotesService.shared.readRaw(filename: filename)

        #expect(raw == "**ID**: `\(id.uuidString)`\n\nUser prefers dark roast coffee.")
    }

    @Test("writeRaw then readRaw round-trips content byte-for-byte, with no header wrapping added")
    func writeRawReadRawRoundTrip() {
        let filename = "test-notes-\(UUID().uuidString).md"
        defer { ConversationNotesService.shared.delete(filename: filename) }
        let content = "**ID**: `12345678-1234-1234-1234-123456789012`\n\nImported from another machine."

        ConversationNotesService.shared.writeRaw(content: content, filename: filename)

        #expect(ConversationNotesService.shared.readRaw(filename: filename) == content)
    }

    @Test("stripIDHeader removes the embedded ID line and following blank line")
    func stripIDHeaderRemovesHeader() {
        let content = "**ID**: `12345678-1234-1234-1234-123456789012`\n\nActual notes content."
        #expect(ConversationNotesService.stripIDHeader(from: content) == "Actual notes content.")
    }

    @Test("stripIDHeader leaves content without the header untouched")
    func stripIDHeaderLeavesUnheaderedContentUntouched() {
        let content = "Just some content, no header."
        #expect(ConversationNotesService.stripIDHeader(from: content) == content)
    }
}
