import { AppNode, NodeType } from "config";
import { Message, MessageType } from "./state";

export interface Validator {
	(nodes: AppNode[]): Message[];
}

function CombineValidators(...v: Validator[]): Validator {
	return (n) => v.flatMap((v) => v(n));
}

function MessageTypeToNumber(t: MessageType) {
	switch (t) {
		case "FATAL":
			return 0;
		case "WARNING":
			return 1;
		case "INFO":
			return 2;
	}
}

function NodeTypeToNumber(t?: NodeType) {
	switch (t) {
		case "github":
			return 0;
		case "app":
			return 1;
		case "volume":
			return 2;
		case "postgresql":
			return 3;
		case "mongodb":
			return 4;
		case "gateway-https":
			return 5;
		case "gateway-tcp":
			return 7;
		case "network":
			return 8;
		case undefined: // For NANode
			return 100;
	}
}

function SortingValidator(v: Validator): Validator {
	return (n) => {
		const nt = new Map(n.map((n) => [n.id, NodeTypeToNumber(n.type)]));
		return v(n).sort((a, b) => {
			const at = MessageTypeToNumber(a.type);
			const bt = MessageTypeToNumber(b.type);
			if (a.nodeId === undefined && b.nodeId === undefined) {
				if (at !== bt) {
					return at - bt;
				}
				return a.id.localeCompare(b.id);
			}
			if (a.nodeId === undefined) {
				return -1;
			}
			if (b.nodeId === undefined) {
				return 1;
			}
			if (a.nodeId === b.nodeId) {
				if (at !== bt) {
					return at - bt;
				}
				return a.id.localeCompare(b.id);
			}
			const ant = nt.get(a.id)!;
			const bnt = nt.get(b.id)!;
			if (ant !== bnt) {
				return ant - bnt;
			}
			return a.id.localeCompare(b.id);
		});
	};
}

export function CreateValidators(): Validator {
	return SortingValidator(
		CombineValidators(
			EmptyValidator,
			GitRepositoryValidator,
			ServiceValidator,
			ServiceAnalyzisValidator,
			GatewayHTTPSValidator,
			GatewayTCPValidator,
		),
	);
}

function EmptyValidator(nodes: AppNode[]): Message[] {
	if (nodes.some((n) => n.type !== "network")) {
		return [];
	}
	return [
		{
			id: "no-nodes",
			type: "FATAL",
			message: "Start by importing application source code",
			onHighlight: (store) => store.setHighlightCategory("repository", true),
			onLooseHighlight: (store) => store.setHighlightCategory("repository", false),
		},
	];
}

function GitRepositoryValidator(nodes: AppNode[]): Message[] {
	const git = nodes.filter((n) => n.type === "github");
	const noAddress: Message[] = git
		.filter((n) => n.data == null || n.data.repository == null)
		.map(
			(n) =>
				({
					id: `${n.id}-no-address`,
					type: "FATAL",
					nodeId: n.id,
					message: "Configure repository address",
					onHighlight: (store) => store.updateNode(n.id, { selected: true }),
					onLooseHighlight: (store) => store.updateNode(n.id, { selected: false }),
				}) satisfies Message,
		);
	const noApp = git
		.filter((n) => !nodes.some((i) => i.type === "app" && i.data?.repository?.repoNodeId === n.id))
		.map(
			(n) =>
				({
					id: `${n.id}-no-app`,
					type: "WARNING",
					nodeId: n.id,
					message: "Connect to service",
					onHighlight: (store) => store.setHighlightCategory("Services", true),
					onLooseHighlight: (store) => store.setHighlightCategory("Services", false),
				}) satisfies Message,
		);
	return noAddress.concat(noApp);
}

function ServiceValidator(nodes: AppNode[]): Message[] {
	const apps = nodes.filter((n) => n.type === "app");
	const noName = apps
		.filter((n) => n.data == null || n.data.label == null || n.data.label === "")
		.map(
			(n): Message => ({
				id: `${n.id}-no-name`,
				type: "FATAL",
				nodeId: n.id,
				message: "Name the service",
				onHighlight: (store) => store.updateNode(n.id, { selected: true }),
				onLooseHighlight: (store) => store.updateNode(n.id, { selected: false }),
				onClick: (store) => {
					store.updateNode(n.id, { selected: true });
					store.updateNodeData<"app">(n.id, {
						activeField: "name",
					});
				},
			}),
		);
	const noSource = apps
		.filter((n) => n.data.type !== "sketch:latest")
		.filter((n) => n.data == null || n.data.repository == null || n.data.repository.repoNodeId === "")
		.map(
			(n): Message => ({
				id: `${n.id}-no-repo`,
				type: "FATAL",
				nodeId: n.id,
				message: "Connect to source repository",
				onHighlight: (store) => store.updateNode(n.id, { selected: true }),
				onLooseHighlight: (store) => store.updateNode(n.id, { selected: false }),
			}),
		);
	const noRuntime = apps
		.filter((n) => n.data == null || n.data.type == null)
		.map(
			(n): Message => ({
				id: `${n.id}-no-runtime`,
				type: "FATAL",
				nodeId: n.id,
				message: "Choose runtime",
				onHighlight: (store) => store.updateNode(n.id, { selected: true }),
				onLooseHighlight: (store) => store.updateNode(n.id, { selected: false }),
				onClick: (store) => {
					store.updateNode(n.id, { selected: true });
					store.updateNodeData<"app">(n.id, {
						activeField: "type",
					});
				},
			}),
		);
	const noPorts = apps
		.filter((n) => n.data == null || n.data.ports == null || n.data.ports.length === 0)
		.map(
			(n): Message => ({
				id: `${n.id}-no-ports`,
				type: "INFO",
				nodeId: n.id,
				message: "Expose ports",
				onHighlight: (store) => store.updateNode(n.id, { selected: true }),
				onLooseHighlight: (store) => store.updateNode(n.id, { selected: false }),
			}),
		);
	const noIngress = apps
		.filter((n) => n.data.type !== "sketch:latest")
		.flatMap((n): Message[] => {
			if (n.data == null) {
				return [];
			}
			return (n.data.ports || [])
				.filter(
					(p) =>
						!nodes
							.filter((i) => i.type === "gateway-https")
							.some((i) => {
								if (
									i.data &&
									i.data.https &&
									i.data.https.serviceId === n.id &&
									i.data.https.portId === p.id
								) {
									return true;
								}
								return false;
							}),
				)
				.map(
					(p): Message => ({
						id: `${n.id}-${p.id}-no-ingress`,
						type: "WARNING",
						nodeId: n.id,
						message: `Connect to gateway: ${p.name} - ${p.value}`,
						onHighlight: (store) => {
							store.updateNode(n.id, { selected: true });
							store.setHighlightCategory("gateways", true);
						},
						onLooseHighlight: (store) => {
							store.updateNode(n.id, { selected: false });
							store.setHighlightCategory("gateways", false);
						},
					}),
				);
		});
	const multipleIngress = apps
		.filter((n) => n.data != null && n.data.ports != null)
		.flatMap((n) =>
			n.data.ports.map((p): Message | undefined => {
				const ing = nodes
					.filter((i) => i.type === "gateway-https")
					.filter(
						(i) =>
							i.data && i.data.https && i.data.https.serviceId === n.id && i.data.https.portId === p.id,
					);
				if (ing.length < 2) {
					return undefined;
				}
				return {
					id: `${n.id}-${p.id}-multiple-ingress`,
					type: "FATAL",
					nodeId: n.id,
					message: `Can not expose same port using multiple ingresses: ${p.name} - ${p.value}`,
					onHighlight: (store) => store.updateNode(n.id, { selected: true }),
					onLooseHighlight: (store) => store.updateNode(n.id, { selected: false }),
				};
			}),
		)
		.filter((m) => m !== undefined);
	return noName.concat(noSource).concat(noRuntime).concat(noPorts).concat(noIngress).concat(multipleIngress);
}

function ServiceAnalyzisValidator(nodes: AppNode[]): Message[] {
	const apps = nodes.filter((n) => n.type === "app");
	return apps
		.filter((n) => n.data.info != null)
		.flatMap((n) => {
			return n.data
				.info!.configVars.map((cv): Message | undefined => {
					if (cv.semanticType === "PORT") {
						if (
							!(n.data.envVars || []).some(
								(p) => ("name" in p && p.name === cv.name) || ("alias" in p && p.alias === cv.name),
							)
						) {
							return {
								id: `${n.id}-missing-port-${cv.name}`,
								type: "WARNING",
								nodeId: n.id,
								message: `Service requires port env variable ${cv.name}`,
							};
						}
					}
					if (cv.category === "EnvironmentVariable") {
						if (
							!(n.data.envVars || []).some(
								(p) => ("name" in p && p.name === cv.name) || ("alias" in p && p.alias === cv.name),
							)
						) {
							if (cv.semanticType === "FILESYSTEM_PATH") {
								return {
									id: `${n.id}-missing-env-${cv.name}`,
									type: "FATAL",
									nodeId: n.id,
									message: `Service requires env variable ${cv.name}, representing filesystem path`,
								};
							} else if (cv.semanticType === "POSTGRES_URL") {
								return {
									id: `${n.id}-missing-env-${cv.name}`,
									type: "FATAL",
									nodeId: n.id,
									message: `Service requires env variable ${cv.name}, representing postgres connection URL`,
								};
							}
						}
					}
					return undefined;
				})
				.filter((m) => m !== undefined);
		});
}

function GatewayHTTPSValidator(nodes: AppNode[]): Message[] {
	const ing = nodes.filter((n) => n.type === "gateway-https");
	const noNetwork: Message[] = ing
		.filter(
			(n) =>
				n.data == null ||
				n.data.network == null ||
				n.data.network == "" ||
				n.data.subdomain == null ||
				n.data.subdomain == "",
		)
		.map(
			(n): Message => ({
				id: `${n.id}-no-network`,
				type: "FATAL",
				nodeId: n.id,
				message: "Network and subdomain must be defined",
				onHighlight: (store) => store.updateNode(n.id, { selected: true }),
				onLooseHighlight: (store) => store.updateNode(n.id, { selected: false }),
			}),
		);
	const notConnected: Message[] = ing
		.filter(
			(n) =>
				n.data == null ||
				n.data.https == null ||
				n.data.https.serviceId == null ||
				n.data.https.serviceId == "" ||
				n.data.https.portId == null ||
				n.data.https.portId == "",
		)
		.map((n) => ({
			id: `${n.id}-not-connected`,
			type: "FATAL",
			nodeId: n.id,
			message: "Connect to a service port",
			onHighlight: (store) => store.updateNode(n.id, { selected: true }),
			onLooseHighlight: (store) => store.updateNode(n.id, { selected: false }),
		}));
	return noNetwork.concat(notConnected);
}

function GatewayTCPValidator(nodes: AppNode[]): Message[] {
	const ing = nodes.filter((n) => n.type === "gateway-tcp");
	const noNetwork: Message[] = ing
		.filter(
			(n) =>
				n.data == null ||
				n.data.network == null ||
				n.data.network == "" ||
				n.data.subdomain == null ||
				n.data.subdomain == "",
		)
		.map(
			(n): Message => ({
				id: `${n.id}-no-network`,
				type: "FATAL",
				nodeId: n.id,
				message: "Network and subdomain must be defined",
				onHighlight: (store) => store.updateNode(n.id, { selected: true }),
				onLooseHighlight: (store) => store.updateNode(n.id, { selected: false }),
			}),
		);
	const notConnected: Message[] = ing
		.filter((n) => n.data == null || n.data.exposed == null || n.data.exposed.length === 0)
		.map((n) => ({
			id: `${n.id}-not-connected`,
			type: "FATAL",
			nodeId: n.id,
			message: "Connect to a service port",
			onHighlight: (store) => store.updateNode(n.id, { selected: true }),
			onLooseHighlight: (store) => store.updateNode(n.id, { selected: false }),
		}));
	return noNetwork.concat(notConnected);
}
