import {
	AppNode,
	BoundEnvVar,
	Env,
	Edge,
	GatewayHttpsNode,
	GatewayTCPNode,
	GithubNode,
	MongoDBNode,
	Network,
	NetworkNode,
	Port,
	PostgreSQLNode,
	ServiceNode,
	VolumeNode,
	Graph,
} from "./graph.js";
import { v4 as uuidv4 } from "uuid";
import { Ingress, Service, Volume, PostgreSQL, MongoDB, Config, PortDomain, isAgent } from "./types.js";
import { GithubRepository } from "./github.js";

export function generateDodoConfig(appId: string | undefined, 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 && !n.data.readonly);
		const tcpNodes = nodes
			.filter((n) => n.type === "gateway-tcp")
			.filter((n) => n.data.exposed !== undefined && !n.data.readonly);
		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(() => ({
								nodeId: i.id,
								network: networkMap.get(i.data.network!)!,
								subdomain: i.data.subdomain!,
								port: { name: sp[2] },
							})),
					);
				});
		};
		const services = nodes
			.filter((n) => n.type === "app")
			.map((n): Service => {
				return {
					nodeId: n.id,
					type: n.data.type,
					name: n.data.label,
					source:
						n.data.repository != undefined
							? {
									repository: nodes
										.filter((i) => i.type === "github")
										.find((i) => i.id === n.data.repository?.repoNodeId)!.data.repository!.sshURL,
									branch:
										n.data.repository != undefined && "branch" in n.data.repository
											? n.data.repository.branch
											: "main",
									rootDir:
										n.data.repository != undefined && "rootDir" in n.data.repository
											? n.data.repository.rootDir
											: "/",
								}
							: undefined,
					ports: (n.data.ports || [])
						.filter((p) => !n.data.dev?.enabled || (p.value != 22 && p.value != 9090))
						.map((p) => ({
							name: p.name.toLowerCase(),
							value: p.value,
							protocol: "TCP", // TODO(gio)
						})),
					env: (n.data.envVars || [])
						.filter((e) => "name" in e)
						.map((e) => {
							if ("value" in e) {
								return { name: e.name, value: e.value };
							}
							return {
								name: e.name,
								alias: "alias" in e ? e.alias : undefined,
							};
						}),
					ingress: ingressNodes
						.filter((i) => i.data.https!.serviceId === n.id)
						.map(
							(i): Ingress => ({
								nodeId: i.id,
								network: networkMap.get(i.data.network!)!,
								subdomain: i.data.subdomain!,
								port: {
									name: n.data.ports.find((p) => p.id === i.data.https!.portId)!.name.toLowerCase(),
								},
								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 }))
						: [],
					dev: n.data.dev?.enabled
						? {
								enabled: true,
								mode: "VM",
								username: env.user.username,
								codeServer:
									n.data.dev.expose != null
										? {
												network: networkMap.get(n.data.dev.expose.network)!,
												subdomain: n.data.dev.expose.subdomain,
											}
										: undefined,
								ssh:
									n.data.dev.expose != null
										? {
												network: networkMap.get(n.data.dev.expose.network)!,
												subdomain: n.data.dev.expose.subdomain,
											}
										: undefined,
							}
						: {
								enabled: false,
							},
					...(n.data.model?.name === "gemini" && {
						model: {
							name: "gemini",
							geminiApiKey: n.data.model.apiKey,
						},
					}),
					...(n.data.model?.name === "claude" && {
						model: {
							name: "claude",
							anthropicApiKey: n.data.model.apiKey,
						},
					}),
				};
			});
		return {
			service: services.filter((s) => !isAgent(s)),
			agent: services.filter(isAgent),
			volume: nodes
				.filter((n) => n.type === "volume")
				.map(
					(n): Volume => ({
						nodeId: n.id,
						name: n.data.label,
						accessMode: n.data.type,
						size: n.data.size,
					}),
				),
			postgresql: nodes
				.filter((n) => n.type === "postgresql")
				.map(
					(n): PostgreSQL => ({
						nodeId: n.id,
						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 => ({
						nodeId: n.id,
						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 function configToGraph(config: Config, networks: Network[], repos: GithubRepository[], current?: Graph): Graph {
	if (current == null) {
		current = { nodes: [], edges: [] };
	}
	const ret: Graph = {
		nodes: [],
		edges: [],
	};
	if (networks.length === 0) {
		return ret;
	}
	const repoNodes = [...(config.service || []), ...(config.agent || [])]
		.filter((s) => s.source?.repository != null)
		.map((s): GithubNode | null => {
			const existing = current.nodes.find(
				(n) => n.type === "github" && n.data.repository?.sshURL === s.source!.repository,
			);
			const repo = repos.find((r) => r.ssh_url === s.source!.repository);
			if (repo == null) {
				return null;
			}
			return {
				id: existing != null ? existing.id : uuidv4(),
				type: "github",
				data: {
					label: repo.full_name,
					repository: {
						id: repo.id,
						sshURL: repo.ssh_url,
						fullName: repo.full_name,
					},
					envVars: [],
					ports: [],
				},
				position:
					existing != null
						? existing.position
						: {
								x: 0,
								y: 0,
							},
			};
		})
		.filter((n) => n != null);
	const networkNodes = networks.map((n): NetworkNode => {
		let existing: NetworkNode | undefined = undefined;
		existing = current.nodes
			.filter((i): i is NetworkNode => i.type === "network")
			.find((i) => i.data.domain === n.domain);
		return {
			id: n.domain,
			type: "network",
			data: {
				label: n.name,
				domain: n.domain,
				envVars: [],
				ports: [],
			},
			position: existing != null ? existing.position : { x: 0, y: 0 },
		};
	});
	const services = [...(config.service || []), ...(config.agent || [])].map((s): ServiceNode => {
		let existing: ServiceNode | null = null;
		if (s.nodeId !== undefined) {
			existing = current.nodes.find((n) => n.id === s.nodeId) as ServiceNode;
		}
		return {
			id: existing != null ? existing.id : uuidv4(),
			type: "app",
			data: {
				label: s.name,
				type: s.type,
				repository:
					s.source != null
						? {
								id: repoNodes.find((r) => r.data.repository?.sshURL === s.source!.repository)!.data
									.repository!.id,
								repoNodeId: repoNodes.find((r) => r.data.repository?.sshURL === s.source!.repository)!
									.id,
								branch: s.source!.branch,
								rootDir: s.source!.rootDir,
							}
						: undefined,
				ports: (s.ports || []).map(
					(p): Port => ({
						id: uuidv4(),
						name: p.name,
						value: p.value,
					}),
				),
				envVars: (s.env || []).map((e): BoundEnvVar => {
					if (e.value != null) {
						return {
							id: uuidv4(),
							source: null,
							name: e.name,
							value: e.value,
						};
					} else if (e.alias != null && e.alias !== "") {
						return {
							id: uuidv4(),
							source: null,
							name: e.name,
							alias: e.alias,
							isEditting: false,
						};
					} else {
						return {
							id: uuidv4(),
							name: e.name,
							source: null,
							isEditting: false,
						};
					}
				}),
				volume: s.volume || [],
				preBuildCommands: s.preBuildCommands?.map((p) => p.bin).join("\n") || "",
				...(s.model != null && {
					model:
						s.model.name === "gemini"
							? { name: "gemini", apiKey: s.model.geminiApiKey }
							: { name: "claude", apiKey: s.model.anthropicApiKey },
				}),
				// TODO(gio): dev
				isChoosingPortToConnect: false,
			},
			// TODO(gio): generate position
			position:
				existing != null
					? existing.position
					: {
							x: 0,
							y: 0,
						},
		};
	});
	const serviceGateways = [...(config.service || []), ...(config.agent || [])]?.flatMap(
		(s, index): GatewayHttpsNode[] => {
			return (s.ingress || []).map((i): GatewayHttpsNode => {
				let existing: GatewayHttpsNode | null = null;
				if (i.nodeId !== undefined) {
					existing = current.nodes.find((n) => n.id === i.nodeId) as GatewayHttpsNode;
				}
				return {
					id: existing != null ? existing.id : uuidv4(),
					type: "gateway-https",
					data: {
						label: i.subdomain,
						envVars: [],
						ports: [],
						network: networks.find((n) => n.name.toLowerCase() === i.network.toLowerCase())!.domain,
						subdomain: i.subdomain,
						https: {
							serviceId: services![index]!.id,
							portId: services![index]!.data.ports.find((p) => {
								const port = i.port;
								if ("name" in port) {
									return p.name === port.name;
								} else {
									return `${p.value}` === port.value;
								}
							})!.id,
						},
						auth: i.auth.enabled
							? {
									enabled: true,
									groups: i.auth.groups || [],
									noAuthPathPatterns: i.auth.noAuthPathPatterns || [],
								}
							: {
									enabled: false,
									groups: [],
									noAuthPathPatterns: [],
								},
					},
					position: {
						x: 0,
						y: 0,
					},
				};
			});
		},
	);
	const exposures = new Map<string, GatewayTCPNode>();
	[...(config.service || []), ...(config.agent || [])]
		?.flatMap((s, index): GatewayTCPNode[] => {
			return (s.expose || []).map((e): GatewayTCPNode => {
				let existing: GatewayTCPNode | null = null;
				if (e.nodeId !== undefined) {
					existing = current.nodes.find((n) => n.id === e.nodeId) as GatewayTCPNode;
				}
				return {
					id: existing != null ? existing.id : uuidv4(),
					type: "gateway-tcp",
					data: {
						label: e.subdomain,
						envVars: [],
						ports: [],
						network: networks.find((n) => n.name.toLowerCase() === e.network.toLowerCase())!.domain,
						subdomain: e.subdomain,
						exposed: [
							{
								serviceId: services![index]!.id,
								portId: services![index]!.data.ports.find((p) => {
									const port = e.port;
									if ("name" in port) {
										return p.name === port.name;
									} else {
										return p.value === port.value;
									}
								})!.id,
							},
						],
					},
					position: existing != null ? existing.position : { x: 0, y: 0 },
				};
			});
		})
		.forEach((n) => {
			const key = `${n.data.network}-${n.data.subdomain}`;
			if (!exposures.has(key)) {
				exposures.set(key, n);
			} else {
				exposures.get(key)!.data.exposed.push(...n.data.exposed);
			}
		});
	const volumes = config.volume?.map((v): VolumeNode => {
		let existing: VolumeNode | null = null;
		if (v.nodeId !== undefined) {
			existing = current.nodes.find((n) => n.id === v.nodeId) as VolumeNode;
		}
		return {
			id: existing != null ? existing.id : uuidv4(),
			type: "volume",
			data: {
				label: v.name,
				type: v.accessMode,
				size: v.size,
				attachedTo: [],
				envVars: [],
				ports: [],
			},
			position:
				existing != null
					? existing.position
					: {
							x: 0,
							y: 0,
						},
		};
	});
	const postgresql = config.postgresql?.map((p): PostgreSQLNode => {
		let existing: PostgreSQLNode | null = null;
		if (p.nodeId !== undefined) {
			existing = current.nodes.find((n) => n.id === p.nodeId) as PostgreSQLNode;
		}
		return {
			id: existing != null ? existing.id : uuidv4(),
			type: "postgresql",
			data: {
				label: p.name,
				envVars: [],
				ports: [
					{
						id: "connection",
						name: "connection",
						value: 5432,
					},
				],
			},
			position:
				existing != null
					? existing.position
					: {
							x: 0,
							y: 0,
						},
		};
	});
	config.postgresql
		?.flatMap((p, index): GatewayTCPNode[] => {
			return (p.expose || []).map((e): GatewayTCPNode => {
				let existing: GatewayTCPNode | null = null;
				if (e.nodeId !== undefined) {
					existing = current.nodes.find((n) => n.id === e.nodeId) as GatewayTCPNode;
				}
				return {
					id: existing != null ? existing.id : uuidv4(),
					type: "gateway-tcp",
					data: {
						label: e.subdomain,
						envVars: [],
						ports: [],
						network: networks.find((n) => n.name.toLowerCase() === e.network.toLowerCase())!.domain,
						subdomain: e.subdomain,
						exposed: [
							{
								serviceId: postgresql![index]!.id,
								portId: "connection",
							},
						],
					},
					position: existing != null ? existing.position : { x: 0, y: 0 },
				};
			});
		})
		.forEach((n) => {
			const key = `${n.data.network}-${n.data.subdomain}`;
			if (!exposures.has(key)) {
				exposures.set(key, n);
			} else {
				exposures.get(key)!.data.exposed.push(...n.data.exposed);
			}
		});
	const mongodb = config.mongodb?.map((m): MongoDBNode => {
		let existing: MongoDBNode | null = null;
		if (m.nodeId !== undefined) {
			existing = current.nodes.find((n) => n.id === m.nodeId) as MongoDBNode;
		}
		return {
			id: existing != null ? existing.id : uuidv4(),
			type: "mongodb",
			data: {
				label: m.name,
				envVars: [],
				ports: [
					{
						id: "connection",
						name: "connection",
						value: 27017,
					},
				],
			},
			position:
				existing != null
					? existing.position
					: {
							x: 0,
							y: 0,
						},
		};
	});
	config.mongodb
		?.flatMap((p, index): GatewayTCPNode[] => {
			return (p.expose || []).map((e): GatewayTCPNode => {
				let existing: GatewayTCPNode | null = null;
				if (e.nodeId !== undefined) {
					existing = current.nodes.find((n) => n.id === e.nodeId) as GatewayTCPNode;
				}
				return {
					id: existing != null ? existing.id : uuidv4(),
					type: "gateway-tcp",
					data: {
						label: e.subdomain,
						envVars: [],
						ports: [],
						network: networks.find((n) => n.name.toLowerCase() === e.network.toLowerCase())!.domain,
						subdomain: e.subdomain,
						exposed: [
							{
								serviceId: mongodb![index]!.id,
								portId: "connection",
							},
						],
					},
					position: existing != null ? existing.position : { x: 0, y: 0 },
				};
			});
		})
		.forEach((n) => {
			const key = `${n.data.network}-${n.data.subdomain}`;
			if (!exposures.has(key)) {
				exposures.set(key, n);
			} else {
				exposures.get(key)!.data.exposed.push(...n.data.exposed);
			}
		});
	ret.nodes = [
		...networkNodes,
		...repoNodes,
		...(services || []),
		...(serviceGateways || []),
		...(volumes || []),
		...(postgresql || []),
		...(mongodb || []),
		...(exposures.values() || []),
	];
	services?.forEach((s) => {
		s.data.envVars.forEach((e) => {
			if (!("name" in e)) {
				return;
			}
			if (!e.name.startsWith("DODO_")) {
				return;
			}
			let r: {
				type: string;
				name: string;
			} | null = null;
			if (e.name.startsWith("DODO_PORT_")) {
				return;
			} else if (e.name.startsWith("DODO_POSTGRESQL_")) {
				r = {
					type: "postgresql",
					name: e.name.replace("DODO_POSTGRESQL_", "").replace("_URL", "").toLowerCase(),
				};
			} else if (e.name.startsWith("DODO_MONGODB_")) {
				r = {
					type: "mongodb",
					name: e.name.replace("DODO_MONGODB_", "").replace("_URL", "").toLowerCase(),
				};
			} else if (e.name.startsWith("DODO_VOLUME_")) {
				r = {
					type: "volume",
					name: e.name.replace("DODO_VOLUME_", "").toLowerCase(),
				};
			}
			if (r != null) {
				e.source = ret.nodes.find((n) => n.type === r.type && n.data.label.toLowerCase() === r.name)!.id;
			}
		});
	});
	const envVarEdges = [...(services || [])].flatMap((n): Edge[] => {
		return n.data.envVars.flatMap((e): Edge[] => {
			if (e.source == null) {
				return [];
			}
			const sn = ret.nodes.find((n) => n.id === e.source!)!;
			const sourceHandle = sn.type === "app" ? "ports" : sn.type === "volume" ? "volume" : "env_var";
			return [
				{
					id: uuidv4(),
					source: e.source!,
					sourceHandle: sourceHandle,
					target: n.id,
					targetHandle: "env_var",
				},
			];
		});
	});
	const exposureEdges = [...exposures.values()].flatMap((n): Edge[] => {
		return n.data.exposed.flatMap((e): Edge[] => {
			return [
				{
					id: uuidv4(),
					source: e.serviceId,
					sourceHandle: ret.nodes.find((n) => n.id === e.serviceId)!.type === "app" ? "ports" : "env_var",
					target: n.id,
					targetHandle: "tcp",
				},
				{
					id: uuidv4(),
					source: n.id,
					sourceHandle: "subdomain",
					target: n.data.network!,
					targetHandle: "subdomain",
				},
			];
		});
	});
	const ingressEdges = [...(serviceGateways || [])].flatMap((n): Edge[] => {
		return [
			{
				id: uuidv4(),
				source: n.data.https!.serviceId,
				sourceHandle: "ports",
				target: n.id,
				targetHandle: "https",
			},
			{
				id: uuidv4(),
				source: n.id,
				sourceHandle: "subdomain",
				target: n.data.network!,
				targetHandle: "subdomain",
			},
		];
	});
	const repoEdges = (services || [])
		.map((s): Edge | null => {
			if (s.data.repository == null) {
				return null;
			}
			return {
				id: uuidv4(),
				source: s.data.repository!.repoNodeId!,
				sourceHandle: "repository",
				target: s.id,
				targetHandle: "repository",
			};
		})
		.filter((e) => e != null);
	ret.edges = [...repoEdges, ...envVarEdges, ...exposureEdges, ...ingressEdges];
	return ret;
}
