import { AppNode, Env, GatewayHttpsNode, Message, MessageType, NodeType, ServiceType, VolumeType } from "./state";

export type AuthDisabled = {
	enabled: false;
};

export type AuthEnabled = {
	enabled: true;
	groups: string[];
	noAuthPathPatterns: string[];
};

export type Auth = AuthDisabled | AuthEnabled;

export type Ingress = {
	network: string;
	subdomain: string;
	port: { name: string } | { value: string };
	auth: Auth;
};

export type Domain = {
	network: string;
	subdomain: string;
};

export type PortValue =
	| {
			name: string;
	  }
	| {
			value: number;
	  };

export type PortDomain = Domain & {
	port: PortValue;
};

export type Service = {
	type: ServiceType;
	name: string;
	source: {
		repository: string;
		branch: string;
		rootDir: string;
	};
	ports?: {
		name: string;
		value: number;
		protocol: "TCP" | "UDP";
	}[];
	env?: {
		name: string;
		alias?: string;
	}[];
	ingress?: Ingress[];
	expose?: PortDomain[];
	volume?: string[];
	preBuildCommands?: { bin: string }[];
};

export type Volume = {
	name: string;
	accessMode: VolumeType;
	size: string;
};

export type PostgreSQL = {
	name: string;
	size: string;
	expose?: Domain[];
};

export type MongoDB = {
	name: string;
	size: string;
	expose?: Domain[];
};

export type Config = {
	service?: Service[];
	volume?: Volume[];
	postgresql?: PostgreSQL[];
	mongodb?: MongoDB[];
};

export function generateDodoConfig(nodes: AppNode[], env: Env): Config | null {
	try {
		const networkMap = new Map(env.networks.map((n) => [n.domain, n.name]));
		const ingressNodes = nodes.filter((n) => n.type === "gateway-https").filter((n) => n.data.https !== undefined);
		const tcpNodes = nodes.filter((n) => n.type === "gateway-tcp").filter((n) => n.data.exposed !== undefined);
		const findExpose = (n: AppNode): PortDomain[] => {
			return n.data.ports
				.map((p) => [n.id, p.id, p.name])
				.flatMap((sp) => {
					return tcpNodes.flatMap((i) =>
						(i.data.exposed || [])
							.filter((t) => t.serviceId === sp[0] && t.portId === sp[1])
							.map(() => ({
								network: networkMap.get(i.data.network!)!,
								subdomain: i.data.subdomain!,
								port: { name: sp[2] },
							})),
					);
				});
		};
		return {
			service: nodes
				.filter((n) => n.type === "app")
				.map((n): Service => {
					return {
						type: n.data.type,
						name: n.data.label,
						source: {
							repository: nodes
								.filter((i) => i.type === "github")
								.find((i) => i.id === n.data.repository.id)!.data.repository!.sshURL,
							branch: n.data.repository.branch,
							rootDir: n.data.repository.rootDir,
						},
						ports: (n.data.ports || []).map((p) => ({
							name: p.name,
							value: p.value,
							protocol: "TCP", // TODO(gio)
						})),
						env: (n.data.envVars || [])
							.filter((e) => "name" in e)
							.map((e) => ({
								name: e.name,
								alias: "alias" in e ? e.alias : undefined,
							})),
						ingress: ingressNodes
							.filter((i) => i.data.https!.serviceId === n.id)
							.map(
								(i: GatewayHttpsNode): Ingress => ({
									network: networkMap.get(i.data.network!)!,
									subdomain: i.data.subdomain!,
									port: {
										name: n.data.ports.find((p) => p.id === i.data.https!.portId)!.name,
									},
									auth:
										i.data.auth?.enabled || false
											? {
													enabled: true,
													groups: i.data.auth!.groups,
													noAuthPathPatterns: i.data.auth!.noAuthPathPatterns,
												}
											: {
													enabled: false,
												},
								}),
							),
						expose: findExpose(n),
						preBuildCommands: n.data.preBuildCommands
							? n.data.preBuildCommands.split("\n").map((cmd) => ({ bin: cmd }))
							: [],
					};
				}),
			volume: nodes
				.filter((n) => n.type === "volume")
				.map(
					(n): Volume => ({
						name: n.data.label,
						accessMode: n.data.type,
						size: n.data.size,
					}),
				),
			postgresql: nodes
				.filter((n) => n.type === "postgresql")
				.map(
					(n): PostgreSQL => ({
						name: n.data.label,
						size: "1Gi", // TODO(gio)
						expose: findExpose(n).map((e) => ({ network: e.network, subdomain: e.subdomain })),
					}),
				),
			mongodb: nodes
				.filter((n) => n.type === "mongodb")
				.map(
					(n): MongoDB => ({
						name: n.data.label,
						size: "1Gi", // TODO(gio)
						expose: findExpose(n).map((e) => ({ network: e.network, subdomain: e.subdomain })),
					}),
				),
		};
	} catch (e) {
		console.log(e);
		return null;
	}
}

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 undefined:
			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,
			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?.id === 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 == null || n.data.repository == null || n.data.repository.id === "")
		.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.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 ingress: ${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 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);
}
