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[] {
	nodes = nodes.filter((n) => n.type !== "network");
	if (nodes.length > 0) {
		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);
}
