/**
 * @file main.c
 * @brief 主程序 — 网络路由拓扑规划系统
 *
 * 完整的菜单循环系统，覆盖10个功能选项：
 *   1. 创建网络拓扑图
 *   2. 查看邻接矩阵(路由表)
 *   3. 全网巡检路线(DFS遍历)
 *   4. 路由环路检测(Kahn拓扑排序)
 *   5. 两设备最优路径查询(Floyd)
 *   6. 全网路由表(Floyd全源最短距离)
 *   7. 光纤布线方案(Prim/Kruskal)
 *   8. 设备详情查询
 *   9. 保存拓扑到文件
 *  10. 从文件加载拓扑
 *   0. 退出系统
 */

#define _CRT_SECURE_NO_WARNINGS 1

#include "main.h"

/* 全局邻接矩阵声明（定义在graph.c中）*/
extern int **parray;

int main()
{
    ALGraph graph;
    int opt;
    int flag = 0;           /* 标记拓扑是否已创建：0=未创建，1=已创建 */
    int pathMat[MAX_DEVICE][MAX_DEVICE];
    int shortPathMat[MAX_DEVICE][MAX_DEVICE];
    char filename[100];

    /* 初始化图结构 */
    graph.deviceNum = 0;
    graph.linkNum = 0;
    parray = NULL;

    while (1)
    {
        showMenu();

        /* 第一层：scanf返回值校验（非数字输入处理） */
        if (scanf("%d", &opt) != 1)
        {
            printf("✘ 输入格式错误，请重新输入数字(0-10)！\n");
            while (getchar() != '\n');   /* 清空输入缓冲区 */
            continue;
        }

        /* 第二层：选项范围校验 */
        if (opt < 0 || opt > 10)
        {
            printf("✘ 无效选项，请输入0-10之间的数字！\n");
            continue;
        }

        /* 第三层：业务依赖校验（必须先建图） */
        if (opt != 1 && opt != 10 && opt != 0 && !flag)
        {
            printf("✘ 请先创建网络拓扑图（选项1）或从文件加载（选项10）！\n");
            continue;
        }

        switch (opt)
        {
        case 0:
            printf("\n感谢使用网络路由拓扑规划系统，再见！\n");
            return 0;

        case 1:
            createGraph(&graph);
            if (graph.deviceNum > 0)
            {
                flag = 1;
                parray = NULL;    /* 重建后邻接矩阵需重新生成 */
            }
            break;

        case 2:
            printGraph(&graph);
            break;

        case 3:
            printf("\n========== 全网设备巡检路线（DFS深度优先遍历）==========\n");
            if (parray == NULL)
            {
                printf("请先选择选项2查看邻接矩阵后再生成巡检路线！\n");
                break;
            }
            /* 直接调用DFS遍历并输出巡检路线 */
            DFSTraverse(graph);
            printf("巡检路线：\n  ");
            {
                int i;
                extern char path[MAX_DEVICE][20];
                for (i = 0; i < graph.deviceNum; i++)
                {
                    printf("%s", path[i]);
                    if (i < graph.deviceNum - 1) printf(" → ");
                }
            }
            printf("\n");
            printf("共巡检 %d 台设备，无重复访问。\n", graph.deviceNum);
            printf("=========================================================\n\n");
            break;

        case 4:
            printf("\n========== 路由环路检测 ==========\n");
            if (parray == NULL)
            {
                printf("请先选择选项2查看邻接矩阵后再检测环路！\n");
                break;
            }
            {
                ALGraph guideGraph;
                guideGraph.deviceNum = 0;
                guideGraph.linkNum = 0;
                /* 生产巡检路线有向图并检测环路 */
                DFSTraverse(graph);
                /* 构造简单导游图：DFS序列作为有向图 */
                int i;
                guideGraph.deviceNum = graph.deviceNum;
                for (i = 0; i < graph.deviceNum; i++)
                {
                    strcpy(guideGraph.devices[i].name, graph.devices[i].name);
                    strcpy(guideGraph.devices[i].desc, graph.devices[i].desc);
                    guideGraph.devices[i].portCount = graph.devices[i].portCount;
                    strcpy(guideGraph.devices[i].note, graph.devices[i].note);
                    guideGraph.devices[i].first = NULL;
                }
                /* 按DFS序列方向建边 */
                extern char path[MAX_DEVICE][20];
                for (i = 0; i < graph.deviceNum - 1; i++)
                {
                    int u = locate(guideGraph, path[i]);
                    int v = locate(guideGraph, path[i + 1]);
                    if (u != -1 && v != -1)
                    {
                        CNode *node = (CNode *)malloc(sizeof(CNode));
                        node->index = v;
                        node->delay = (parray[u][v] < INF) ? parray[u][v] : 1;
                        node->next = guideGraph.devices[u].first;
                        guideGraph.devices[u].first = node;
                        guideGraph.linkNum++;
                    }
                }
                loopTest(guideGraph);
            }
            break;

        case 5:
            minDistance(graph, pathMat, shortPathMat);
            break;

        case 6:
            floydAllDistance(graph, pathMat, shortPathMat);
            break;

        case 7:
            printf("\n========== 光纤骨干网布线方案 ==========\n");
            primMST(graph);
            kruskalMST(graph);
            break;

        case 8:
            showDeviceInfo(graph);
            break;

        case 9:
            printf("请输入保存文件名（如：network_topology.txt）：");
            scanf("%s", filename);
            saveGraphToFile(&graph, filename);
            break;

        case 10:
            printf("请输入加载文件名（如：network_topology.txt）：");
            scanf("%s", filename);
            loadGraphFromFile(&graph, filename);
            if (graph.deviceNum > 0)
            {
                flag = 1;
                parray = NULL;    /* 加载后需重新生成邻接矩阵 */
            }
            break;

        default:
            /* 理论上不会执行到此（范围已校验） */
            break;
        }
    }

    return 0;
}
