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);
}
