import { describe, expect, test } from "bun:test"
import { getMemoryBaseDir, getMemoryDir, getMemoryEntrypoint, isMemoryPath } from "@/saeeol/memory/paths"

describe("getMemoryBaseDir", () => {
  test("returns default path without env override", () => {
    const orig = process.env.SAEEOL_MEMORY_DIR
    delete process.env.SAEEOL_MEMORY_DIR
    const dir = getMemoryBaseDir()
    expect(dir).toContain("saeeol")
    expect(dir).toContain(".config")
    process.env.SAEEOL_MEMORY_DIR = orig
  })

  test("uses env override when set", () => {
    const orig = process.env.SAEEOL_MEMORY_DIR
    process.env.SAEEOL_MEMORY_DIR = "/custom/memory"
    expect(getMemoryBaseDir()).toBe("/custom/memory")
    process.env.SAEEOL_MEMORY_DIR = orig
  })
})

describe("getMemoryDir", () => {
  test("returns path with project root sanitized", () => {
    const orig = process.env.SAEEOL_MEMORY_DIR
    delete process.env.SAEEOL_MEMORY_DIR
    const dir = getMemoryDir("/home/user/my-project")
    expect(dir).toContain("memory")
    expect(dir).toContain("projects")
    process.env.SAEEOL_MEMORY_DIR = orig
  })

  test("sanitizes special characters", () => {
    const orig = process.env.SAEEOL_MEMORY_DIR
    delete process.env.SAEEOL_MEMORY_DIR
    const dir = getMemoryDir('C:\\Users<test>project|name')
    expect(dir).not.toContain("<")
    expect(dir).not.toContain(">")
    expect(dir).not.toContain("|")
    // colons in drive letter (C:) are preserved in the result path itself
    process.env.SAEEOL_MEMORY_DIR = orig
  })

  test("uses env override directly", () => {
    const orig = process.env.SAEEOL_MEMORY_DIR
    process.env.SAEEOL_MEMORY_DIR = "/override/memory"
    expect(getMemoryDir("/any/project")).toBe("/override/memory")
    process.env.SAEEOL_MEMORY_DIR = orig
  })

  test("ends with separator", () => {
    const orig = process.env.SAEEOL_MEMORY_DIR
    delete process.env.SAEEOL_MEMORY_DIR
    const dir = getMemoryDir("/test/project")
    expect(dir.endsWith("/") || dir.endsWith("\\")).toBe(true)
    process.env.SAEEOL_MEMORY_DIR = orig
  })
})

describe("getMemoryEntrypoint", () => {
  test("returns MEMORY.md path", () => {
    const orig = process.env.SAEEOL_MEMORY_DIR
    delete process.env.SAEEOL_MEMORY_DIR
    const ep = getMemoryEntrypoint("/test/project")
    expect(ep).toContain("MEMORY.md")
    expect(ep).toContain("memory")
    process.env.SAEEOL_MEMORY_DIR = orig
  })
})

describe("isMemoryPath", () => {
  test("returns true for path inside memory dir", () => {
    const orig = process.env.SAEEOL_MEMORY_DIR
    delete process.env.SAEEOL_MEMORY_DIR
    const dir = getMemoryDir("/test/project")
    expect(isMemoryPath(dir + "notes.md", "/test/project")).toBe(true)
    expect(isMemoryPath(dir + "sub/file.md", "/test/project")).toBe(true)
    process.env.SAEEOL_MEMORY_DIR = orig
  })

  test("returns false for path outside memory dir", () => {
    const orig = process.env.SAEEOL_MEMORY_DIR
    delete process.env.SAEEOL_MEMORY_DIR
    expect(isMemoryPath("/tmp/other.md", "/test/project")).toBe(false)
    expect(isMemoryPath("/home/user/file.md", "/test/project")).toBe(false)
    process.env.SAEEOL_MEMORY_DIR = orig
  })
})
