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.address,
                        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.address == null || n.data.address === "").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);
}
