import { describe, expect, it } from "vitest";
import {
	BUILTIN_WIDGETS,
	SERVICE_REGISTRY,
	getBuiltinBinding,
	getServiceBinding,
	resolveWidget,
} from "./registry";
import type { ServiceInstance, WidgetInstance } from "../types";

describe("service registry", () => {
	it("registers the backend service types", () => {
		expect(Object.keys(SERVICE_REGISTRY).sort()).toEqual([
			"alertmanager",
			"jellyfin",
			"nextcloud",
			"prometheus",
			"qbittorrent",
			"ssh_tasks",
		]);
	});

	it("binds widget kinds per service", () => {
		expect(SERVICE_REGISTRY.prometheus.widgets.map((w) => w.kind)).toEqual([
			"metric",
			"chart",
			"gauge",
			"mean",
		]);
		expect(SERVICE_REGISTRY.alertmanager.widgets.map((w) => w.kind)).toEqual([
			"active_alerts",
		]);
		expect(SERVICE_REGISTRY.ssh_tasks.widgets.map((w) => w.kind)).toEqual([
			"task_output",
		]);
		expect(SERVICE_REGISTRY.nextcloud.widgets).toEqual([]);
	});

	it("registers the two built-in widget kinds", () => {
		expect(Object.keys(BUILTIN_WIDGETS).sort()).toEqual(["backups", "static"]);
	});

	it("resolves a prometheus metric widget via the services list", () => {
		const widget: WidgetInstance = {
			id: "w1",
			service_id: "s1",
			widget_kind: "metric",
			title: "Metric",
			config: {},
			enabled: true,
			sort_order: 0,
			created_at: 0,
			updated_at: 0,
		};
		const services: ServiceInstance[] = [
			{
				id: "s1",
				service_type: "prometheus",
				name: "Prometheus",
				config: { base_url: "https://prometheus.example.com" },
				secrets_set: { api_key: true },
				enabled: true,
				created_at: 0,
				updated_at: 0,
			},
		];
		const resolved = resolveWidget(widget, services);
		expect(resolved).toBeDefined();
		expect(resolved?.refreshIntervalMs).toBe(30_000);
	});

	it("resolves an alertmanager active_alerts widget", () => {
		const widget: WidgetInstance = {
			id: "wam",
			service_id: "sam",
			widget_kind: "active_alerts",
			title: "Alerts",
			config: {},
			enabled: true,
			sort_order: 0,
			created_at: 0,
			updated_at: 0,
		};
		const services: ServiceInstance[] = [
			{
				id: "sam",
				service_type: "alertmanager",
				name: "Alertmanager",
				config: { base_url: "http://am:9093" },
				secrets_set: {},
				enabled: true,
				created_at: 0,
				updated_at: 0,
			},
		];
		const resolved = resolveWidget(widget, services);
		expect(resolved).toBeDefined();
		expect(resolved?.refreshIntervalMs).toBe(30_000);
	});

	it("resolves a built-in widget without a service", () => {
		const widget: WidgetInstance = {
			id: "w2",
			service_id: null,
			widget_kind: "static",
			title: "Note",
			config: { text: "hi" },
			enabled: true,
			sort_order: 0,
			created_at: 0,
			updated_at: 0,
		};
		const resolved = resolveWidget(widget, []);
		expect(resolved).toBeDefined();
	});

	it("returns undefined for an unknown widget kind", () => {
		const widget: WidgetInstance = {
			id: "w3",
			service_id: null,
			widget_kind: "bogus",
			title: "x",
			config: {},
			enabled: true,
			sort_order: 0,
			created_at: 0,
			updated_at: 0,
		};
		expect(resolveWidget(widget, [])).toBeUndefined();
	});

	it("lookups return undefined for unknown types", () => {
		expect(getServiceBinding("nope")).toBeUndefined();
		expect(getBuiltinBinding("nope")).toBeUndefined();
	});
});
