import { describe, expect, it } from "vitest";
import {
	completeSfEnvSchema,
	getCompleteSfEnv,
	getEnvValidationSummary,
	getSfEnv,
	parseCompleteSfEnv,
	parseSfEnv,
	sfEnvSchema,
} from "../env";

describe("env schema", () => {
	describe("sfEnvSchema (minimal)", () => {
		it("parses valid SF_* variables", () => {
			const result = sfEnvSchema.safeParse({
				SF_HOME: "/home/user/.sf",
				SF_VERSION: "2.75.3",
				SF_BIN_PATH: "/usr/local/bin/sf",
			});
			expect(result.success).toBe(true);
		});

		it("allows missing optional variables", () => {
			const result = sfEnvSchema.safeParse({});
			expect(result.success).toBe(true);
		});

		it("validates SF_PROJECT_ID format", () => {
			const valid = sfEnvSchema.safeParse({ SF_PROJECT_ID: "my-project_123" });
			expect(valid.success).toBe(true);

			const invalid = sfEnvSchema.safeParse({
				SF_PROJECT_ID: "invalid@project",
			});
			expect(invalid.success).toBe(false);
		});

		it("parses boolean SF_WEB_DAEMON_MODE as 0 or 1", () => {
			const result = sfEnvSchema.safeParse({ SF_WEB_DAEMON_MODE: "1" });
			expect(result.success).toBe(true);
			if (result.success) {
				expect(result.data.SF_WEB_DAEMON_MODE).toBe(true);
			}
		});
	});

	describe("completeSfEnvSchema (comprehensive)", () => {
		it("includes all minimal schema fields", () => {
			const result = completeSfEnvSchema.safeParse({
				SF_HOME: "/home/user/.sf",
				SF_VERSION: "2.75.3",
			});
			expect(result.success).toBe(true);
		});

		it("parses boolean flags as 0 or 1", () => {
			const result = completeSfEnvSchema.safeParse({
				SF_DEBUG: "1",
				SF_QUIET: "0",
				SF_RTK_DISABLED: "1",
			});
			expect(result.success).toBe(true);
			if (result.success) {
				expect(result.data.SF_DEBUG).toBe(true);
				expect(result.data.SF_QUIET).toBe(false);
				expect(result.data.SF_RTK_DISABLED).toBe(true);
			}
		});

		it("parses enum fields with valid values", () => {
			const result = completeSfEnvSchema.safeParse({
				SF_PERMISSION_LEVEL: "medium",
				SF_GEMINI_PERMISSION_MODE: "ask",
				SF_DOCTOR_SCOPE: "deep",
			});
			expect(result.success).toBe(true);
			if (result.success) {
				expect(result.data.SF_PERMISSION_LEVEL).toBe("medium");
			}
		});

		it("rejects invalid enum values", () => {
			const result = completeSfEnvSchema.safeParse({
				SF_PERMISSION_LEVEL: "invalid",
			});
			expect(result.success).toBe(false);
		});

		it("parses positive integer fields", () => {
			const result = completeSfEnvSchema.safeParse({
				SF_RTK_REWRITE_TIMEOUT_MS: "5000",
				SF_CIRCUIT_BREAKER_FAILURE_THRESHOLD: "10",
			});
			expect(result.success).toBe(true);
			if (result.success) {
				expect(result.data.SF_RTK_REWRITE_TIMEOUT_MS).toBe(5000);
				expect(result.data.SF_CIRCUIT_BREAKER_FAILURE_THRESHOLD).toBe(10);
			}
		});

		it("rejects negative or non-integer values for numeric fields", () => {
			const result = completeSfEnvSchema.safeParse({
				SF_RTK_REWRITE_TIMEOUT_MS: "-5000",
			});
			expect(result.success).toBe(false);
		});
	});

	describe("parseSfEnv", () => {
		it("returns typed object with minimal fields", () => {
			const env = {
				SF_HOME: "/home/user/.sf",
				SF_VERSION: "2.75.3",
			};
			const result = parseSfEnv(env);
			expect(result.SF_HOME).toBe("/home/user/.sf");
			expect(result.SF_VERSION).toBe("2.75.3");
		});

		it("uses process.env by default", () => {
			const result = parseSfEnv();
			expect(result).toBeDefined();
		});
	});

	describe("parseCompleteSfEnv", () => {
		it("returns parsed complete environment", () => {
			const env = {
				SF_HOME: "/home/user/.sf",
				SF_DEBUG: "1",
				SF_QUIET: "0",
			};
			const result = parseCompleteSfEnv(env);
			expect(result.SF_HOME).toBe("/home/user/.sf");
			expect(result.SF_DEBUG).toBe(true);
			expect(result.SF_QUIET).toBe(false);
		});

		it("returns empty object on parse failure (graceful degradation)", () => {
			const env = {
				SF_PERMISSION_LEVEL: "invalid_value",
			};
			const result = parseCompleteSfEnv(env);
			// Should degrade gracefully, not throw
			expect(result).toBeDefined();
		});
	});

	describe("getSfEnv", () => {
		it("applies default SF_HOME if not set", () => {
			const result = getSfEnv({});
			expect(result.sfHome).toBeDefined();
			expect(result.sfHome.endsWith(".sf")).toBe(true);
		});

		it("uses provided SF_HOME", () => {
			const result = getSfEnv({ SF_HOME: "/custom/.sf" });
			expect(result.sfHome).toBe("/custom/.sf");
		});

		it("applies default agentDir if not set", () => {
			const result = getSfEnv({ SF_HOME: "/home/user/.sf" });
			expect(result.agentDir).toBe("/home/user/.sf/agent");
		});

		it("prefers SF_AGENT_DIR over SF_CODING_AGENT_DIR", () => {
			const result = getSfEnv({
				SF_HOME: "/home/user/.sf",
				SF_AGENT_DIR: "/custom/agent1",
				SF_CODING_AGENT_DIR: "/custom/agent2",
			});
			expect(result.agentDir).toBe("/custom/agent1");
		});
	});

	describe("getCompleteSfEnv", () => {
		it("returns complete environment with computed defaults", () => {
			const result = getCompleteSfEnv({
				SF_HOME: "/home/user/.sf",
				SF_DEBUG: "1",
			});
			expect(result.sfHome).toBe("/home/user/.sf");
			expect(result.stateDir).toBe("/home/user/.sf");
			expect(result.SF_DEBUG).toBe(true);
		});

		it("computes stateDir from SF_STATE_DIR if provided", () => {
			const result = getCompleteSfEnv({
				SF_HOME: "/home/user/.sf",
				SF_STATE_DIR: "/custom/state",
			});
			expect(result.stateDir).toBe("/custom/state");
		});

		it("defaults stateDir to sfHome if SF_STATE_DIR not set", () => {
			const result = getCompleteSfEnv({
				SF_HOME: "/home/user/.sf",
			});
			expect(result.stateDir).toBe("/home/user/.sf");
		});
	});

	describe("getEnvValidationSummary", () => {
		it("reports which variables are configured vs defaults", () => {
			const env = {
				SF_HOME: "/home/user/.sf",
				SF_DEBUG: "1",
			};
			const summary = getEnvValidationSummary(env);
			expect(summary.configured).toContain("SF_HOME");
			expect(summary.configured).toContain("SF_DEBUG");
			expect(summary.total).toBeGreaterThan(0);
			expect(summary.defaults.length).toBeLessThan(summary.total);
		});

		it("counts total known variables", () => {
			const summary = getEnvValidationSummary({});
			// Should have significant number of known vars
			expect(summary.total).toBeGreaterThan(50);
		});
	});

	describe("integration", () => {
		it("round-trips env values through parsing", () => {
			const original = {
				SF_HOME: "/home/user/.sf",
				SF_DEBUG: "1",
				SF_RTK_REWRITE_TIMEOUT_MS: "5000",
			};
			const complete = getCompleteSfEnv(original);
			expect(complete.SF_HOME).toBe("/home/user/.sf");
			expect(complete.SF_DEBUG).toBe(true);
			expect(complete.SF_RTK_REWRITE_TIMEOUT_MS).toBe(5000);
		});

		it("handles empty environment gracefully", () => {
			const complete = getCompleteSfEnv({});
			expect(complete.sfHome).toBeDefined();
			expect(complete.stateDir).toBeDefined();
			expect(complete.agentDir).toBeDefined();
		});
	});
});
