-- SPDX-FileCopyrightText: Amolith <amolith@secluded.site>
--
-- SPDX-License-Identifier: GPL-3.0-or-later

-- Load main.lua as a module (it exports functions when required)
package.path = package.path .. ";./?.lua"
local wt = dofile("src/main.lua")

describe("split_path", function()
	describe("basic paths", function()
		it("splits absolute path into components", function()
			local parts = wt.split_path("/home/user/project")
			assert.are.same({ "home", "user", "project" }, parts)
		end)

		it("splits relative path into components", function()
			local parts = wt.split_path("a/b/c")
			assert.are.same({ "a", "b", "c" }, parts)
		end)

		it("handles single component", function()
			local parts = wt.split_path("single")
			assert.are.same({ "single" }, parts)
		end)
	end)

	describe("edge cases", function()
		it("returns empty table for root path", function()
			local parts = wt.split_path("/")
			assert.are.same({}, parts)
		end)

		it("returns empty table for empty string", function()
			local parts = wt.split_path("")
			assert.are.same({}, parts)
		end)

		it("collapses multiple slashes", function()
			local parts = wt.split_path("/a//b///c/")
			assert.are.same({ "a", "b", "c" }, parts)
		end)

		it("ignores trailing slash", function()
			local parts = wt.split_path("/a/b/c/")
			assert.are.same({ "a", "b", "c" }, parts)
		end)

		it("handles multiple leading slashes", function()
			local parts = wt.split_path("///a/b")
			assert.are.same({ "a", "b" }, parts)
		end)
	end)

	describe("special characters", function()
		it("preserves dots in path components", function()
			local parts = wt.split_path("/home/user/.config")
			assert.are.same({ "home", "user", ".config" }, parts)
		end)

		it("preserves hyphens in path components", function()
			local parts = wt.split_path("/my-project/sub-dir")
			assert.are.same({ "my-project", "sub-dir" }, parts)
		end)

		it("preserves spaces in path components", function()
			local parts = wt.split_path("/path with/spaces here")
			assert.are.same({ "path with", "spaces here" }, parts)
		end)
	end)
end)

describe("branch_to_path", function()
	describe("nested style (default)", function()
		it("preserves slashes in branch name", function()
			local path = wt.branch_to_path("/repo", "feature/auth", "nested")
			assert.are.equal("/repo/feature/auth", path)
		end)

		it("handles simple branch name", function()
			local path = wt.branch_to_path("/repo", "main", "nested")
			assert.are.equal("/repo/main", path)
		end)

		it("handles deeply nested branch", function()
			local path = wt.branch_to_path("/repo", "feature/auth/oauth2", "nested")
			assert.are.equal("/repo/feature/auth/oauth2", path)
		end)
	end)

	describe("flat style", function()
		it("replaces slashes with default separator", function()
			local path = wt.branch_to_path("/repo", "feature/auth", "flat")
			assert.are.equal("/repo/feature_auth", path)
		end)

		it("uses custom separator", function()
			local path = wt.branch_to_path("/repo", "feature/auth", "flat", "-")
			assert.are.equal("/repo/feature-auth", path)
		end)

		it("handles simple branch name (no slashes)", function()
			local path = wt.branch_to_path("/repo", "main", "flat")
			assert.are.equal("/repo/main", path)
		end)

		it("handles multiple slashes with custom separator", function()
			local path = wt.branch_to_path("/repo", "a/b/c", "flat", ".")
			assert.are.equal("/repo/a.b.c", path)
		end)
	end)

	describe("edge cases", function()
		it("handles empty branch name", function()
			local path = wt.branch_to_path("/repo", "", "nested")
			assert.are.equal("/repo/", path)
		end)

		it("handles root ending with slash", function()
			local path = wt.branch_to_path("/repo/", "main", "nested")
			-- Results in double slash - document this behavior
			assert.are.equal("/repo//main", path)
		end)

		it("handles separator containing percent", function()
			assert.are.equal("/repo/a%b", wt.branch_to_path("/repo", "a/b", "flat", "%"))
		end)

		it("handles branch starting with slash", function()
			local path = wt.branch_to_path("/repo", "/feature", "nested")
			-- Results in double slash
			assert.are.equal("/repo//feature", path)
		end)
	end)

	describe("common branch naming patterns", function()
		it("handles issue-number branches", function()
			local path = wt.branch_to_path("/repo", "847-do-a-thing", "nested")
			assert.are.equal("/repo/847-do-a-thing", path)
		end)

		it("handles version branches", function()
			local path = wt.branch_to_path("/repo", "release/1.2.3", "flat", "_")
			assert.are.equal("/repo/release_1.2.3", path)
		end)

		it("handles user prefix branches", function()
			local path = wt.branch_to_path("/repo", "user/alice/feature", "flat", "-")
			assert.are.equal("/repo/user-alice-feature", path)
		end)
	end)
end)

describe("relative_path", function()
	describe("sibling directories", function()
		it("computes path to sibling", function()
			local rel = wt.relative_path("/a/b", "/a/c")
			assert.are.equal("../c", rel)
		end)

		it("computes path to sibling's child", function()
			local rel = wt.relative_path("/a/b", "/a/c/d")
			assert.are.equal("../c/d", rel)
		end)
	end)

	describe("parent/child relationships", function()
		it("computes path to child", function()
			local rel = wt.relative_path("/a", "/a/b")
			assert.are.equal("b", rel)
		end)

		it("computes path to deeply nested child", function()
			local rel = wt.relative_path("/a", "/a/b/c/d")
			assert.are.equal("b/c/d", rel)
		end)

		it("computes path to parent", function()
			local rel = wt.relative_path("/a/b/c", "/a")
			assert.are.equal("../..", rel)
		end)
	end)

	describe("same path", function()
		it("returns ./ for identical paths", function()
			local rel = wt.relative_path("/a/b", "/a/b")
			assert.are.equal("./", rel)
		end)
	end)

	describe("completely different paths", function()
		it("computes path across directory tree", function()
			local rel = wt.relative_path("/home/alice/projects", "/var/log")
			assert.are.equal("../../../var/log", rel)
		end)
	end)

	describe("root paths", function()
		it("handles from root to child", function()
			local rel = wt.relative_path("/", "/a/b")
			assert.are.equal("a/b", rel)
		end)

		it("handles from child to root", function()
			local rel = wt.relative_path("/a/b", "/")
			assert.are.equal("../..", rel)
		end)
	end)

	describe("edge cases", function()
		it("handles trailing slash in from path", function()
			-- split_path normalizes trailing slashes
			local rel = wt.relative_path("/a/b/", "/a/c")
			assert.are.equal("../c", rel)
		end)

		it("handles paths with common deep prefix", function()
			local rel = wt.relative_path("/repo/project/src/lib", "/repo/project/src/bin")
			assert.are.equal("../bin", rel)
		end)
	end)

	describe("real-world wt scenarios", function()
		it("computes path from worktree to .bare", function()
			local rel = wt.relative_path("/projects/myapp/feature/auth", "/projects/myapp/.bare")
			assert.are.equal("../../.bare", rel)
		end)

		it("computes path between worktrees", function()
			local rel = wt.relative_path("/projects/myapp/main", "/projects/myapp/feature/new")
			assert.are.equal("../feature/new", rel)
		end)
	end)
end)
