package com.ruoyi.app.user;

import com.ruoyi.app.mendian.FoodSpecController;
import com.ruoyi.app.mendian.PosFenleiController;
import com.ruoyi.app.mendian.PosFoodController;
import com.ruoyi.app.mendian.PosStoreController;
import com.ruoyi.app.order.PosOrderController;
import com.ruoyi.app.order.PosOrderShOprateController;
import com.ruoyi.system.utils.Auth;
import org.junit.jupiter.api.Test;

import java.lang.reflect.Method;
import java.util.Arrays;

import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertTrue;

class MerchantSessionAuthAnnotationTest {

    @Test
    void merchantEndpointsRequireServerSessionValidation() {
        assertSessionAuth(MerchantSubaccountController.class,
                "list", "create", "update", "updatePassword", "updateStatus");
        assertSessionAuth(InfoUserController.class, "merchantLogout");
        assertSessionAuth(FoodSpecController.class,
                "foodSpecPageList", "saveFoodSpec", "getSpecs", "deleteFoodSpec",
                "getAvailableSpecsList", "changeOpen", "changeSpecValueOpen");
        assertSessionAuth(PosFenleiController.class, "delefenlei", "addfenlei");
        assertSessionAuth(PosFoodController.class,
                "delefood", "changerecommend", "setposfood", "getidlist", "getFoodPageList");
        assertSessionAuth(PosStoreController.class,
                "delemendian", "storelistlist", "getmystorelist", "addmendian",
                "getMdBusinessHours", "saveMdBusinessHours");
        assertSessionAuth(PosOrderController.class,
                "setorderuzt", "getorderxq", "getstoreorderlist");
        assertSessionAuth(PosOrderShOprateController.class,
                "getInvoice", "invalidInvoice", "createOrder", "acceptOrder", "dispatchOrder",
                "completeOrder", "confirmCashPayment", "cancelOrder", "orderList", "orderDetail");
    }

    private void assertSessionAuth(Class<?> controllerType, String... methodNames) {
        for (String methodName : methodNames) {
            Method method = Arrays.stream(controllerType.getDeclaredMethods())
                    .filter(candidate -> candidate.getName().equals(methodName))
                    .findFirst()
                    .orElseThrow(() -> new AssertionError(controllerType.getSimpleName()
                            + "." + methodName + " not found"));
            Auth auth = method.getAnnotation(Auth.class);
            assertNotNull(auth, controllerType.getSimpleName() + "." + methodName
                    + " must declare @Auth");
            assertTrue(auth.session(), controllerType.getSimpleName() + "." + methodName
                    + " must validate the Redis session");
        }
    }
}
