package com.aps.macroplanner;

import com.aps.ApsApplication;
import com.aps.macroplanner.data.DataValidator;
import com.aps.macroplanner.data.MacroPlannerDataConverter;
import com.aps.macroplanner.data.TestDataBuilder;
import com.google.ortools.Loader;
import org.springframework.boot.SpringApplication;
import org.springframework.context.ApplicationContext;

/**
 * 数据库工艺物料类 → macroplanner 转换器测试运行器。
 *
 * <p>通过 Spring 启动获取 {@link MacroPlannerDataConverter} Bean,
 * 从数据库加载指定场景的工艺物料数据并转换为 {@link TestDataBuilder},
 * 然后用 {@link DataValidator} 验证 + {@link MacroPlannerOptimizer} 求解。</p>
 *
 * <h3>验证流程</h3>
 * <ol>
 *   <li>调用 converter.convert(sceneId) 从数据库转换数据</li>
 *   <li>打印转换后的实体规模 (products/operations/routings/...)</li>
 *   <li>DataValidator 验证数据完整性 (引用完整性、非负数等)</li>
 *   <li>MacroPlannerOptimizer 构建模型并求解</li>
 * </ol>
 *
 * <p>用法: {@code java MacroPlannerDataConverterRunner <sceneId>}</p>
 */
public class MacroPlannerDataConverterRunner {

    public static void main(String[] args) {
        String sceneId = (args.length > 0) ? args[0] : "B288477F1A594DB584C87EEA77880AA3";

        System.out.println("===== MACROPLANNER DATA CONVERTER RUNNER START =====");
        System.out.println("SceneId: " + sceneId);

        ApplicationContext ctx = SpringApplication.run(ApsApplication.class, args);
        try {
            MacroPlannerDataConverter converter = ctx.getBean(MacroPlannerDataConverter.class);

            // 1. 转换数据: 数据库工艺物料类 → macroplanner 实体
            TestDataBuilder data = converter.convert(sceneId);

            // 2. 打印转换结果规模
            System.out.println("Data converted:");
            System.out.println("  Products:            " + data.getProducts().size());
            System.out.println("  StockingPoints:      " + data.getStockingPoints().size());
            System.out.println("  Operations:          " + data.getOperations().size());
            System.out.println("  Routings:            " + data.getRoutings().size());
            System.out.println("  OperationInputs:     " + data.getOperationInputs().size());
            System.out.println("  InitialInventories:  " + data.getInitialInventories().size());
            System.out.println("  InTransitSupplies:   " + data.getInTransitSupplies().size());
            System.out.println("  SalesDemands:        " + data.getSalesDemands().size());
            System.out.println("  Periods:             " + data.getPeriods().size());
            System.out.println("  UnitPeriods:         " + data.getUnitPeriods().size());

            // 3. DataValidator 验证数据完整性
            DataValidator validator = new DataValidator(data);
            boolean valid = validator.validate();
            if (validator.hasErrors()) {
                System.err.println("DataValidator ERRORS (" + validator.getErrors().size() + "):");
                validator.getErrors().forEach(e -> System.err.println("  [ERROR] " + e));
            }
            if (validator.hasWarnings()) {
                System.out.println("DataValidator WARNINGS (" + validator.getWarnings().size() + "):");
                validator.getWarnings().forEach(w -> System.out.println("  [WARN]  " + w));
            }
            System.out.println("DataValidator: valid=" + valid);

            if (!valid) {
                System.err.println("数据验证失败, 跳过求解。请检查上述 ERROR。");
                return;
            }

            // 4. 喂给优化器求解
            Loader.loadNativeLibraries();
            MacroPlannerOptimizer optimizer = new MacroPlannerOptimizer(data);
            optimizer.buildModel();
            optimizer.solve();

            System.out.println("===== MACROPLANNER DATA CONVERTER RUNNER END =====");
        } finally {
            SpringApplication.exit(ctx);
        }
    }
}
