package com.njcn.system.controller;


import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.njcn.common.pojo.annotation.OperateInfo;
import com.njcn.common.pojo.constant.OperateType;
import com.njcn.common.pojo.enums.common.DataStateEnum;
import com.njcn.common.pojo.enums.common.LogEnum;
import com.njcn.common.pojo.enums.response.CommonResponseEnum;
import com.njcn.common.pojo.exception.BusinessException;
import com.njcn.common.pojo.response.HttpResult;
import com.njcn.common.utils.HttpResultUtil;
import com.njcn.common.utils.LogUtil;
import com.njcn.system.enums.SystemResponseEnum;
import com.njcn.system.pojo.param.ConfigParam;
import com.njcn.system.pojo.po.Config;
import com.njcn.system.service.IConfigService;
import com.njcn.web.controller.BaseController;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.CollectionUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.Objects;

/**
 * <p>
 * 前端控制器
 * </p>
 *
 * @author hongawen
 * @since 2021-12-13
 */
@Slf4j
@Api(tags = "系统配置操作")
@RestController
@RequestMapping("/config")
@RequiredArgsConstructor
public class ConfigController extends BaseController {

    private final IConfigService iConfigService;



    @OperateInfo(info = LogEnum.SYSTEM_COMMON)
    @GetMapping("/getSysConfig")
    @ApiOperation("获取系统配置")
    public HttpResult<Config> getSysConfig() {
        String methodDescribe = getMethodDescribe("getSysConfig");
        LogUtil.njcnDebug(log, "{}", methodDescribe, methodDescribe);
        Config config = iConfigService.lambdaQuery()
                .eq(Config::getState, DataStateEnum.ENABLE.getCode())
                .one();
        if (Objects.isNull(config)) {
            return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.NO_DATA, null, methodDescribe);
        } else {
            return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, config, methodDescribe);
        }
    }


    @OperateInfo(info = LogEnum.SYSTEM_COMMON)
    @GetMapping("/getSysConfigData")
    @ApiOperation("获取系统配置列表")
    public HttpResult<List<Config>> getSysConfigData() {
        String methodDescribe = getMethodDescribe("getSysConfigData");
        LogUtil.njcnDebug(log, "{}", methodDescribe, methodDescribe);
        List<Config> res = iConfigService.getList();
        if (CollectionUtils.isEmpty(res)) {
            return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.NO_DATA, null, methodDescribe);
        } else {
            return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, res, methodDescribe);
        }
    }


    @OperateInfo(info = LogEnum.SYSTEM_COMMON)
    @GetMapping("/getSysConfigById")
    @ApiOperation("根据配置Id获取系统配置")
    @ApiImplicitParam(name = "id", value = "参数id", required = true)
    public HttpResult<Config> getSysConfigById(@RequestParam("id") String id) {
        String methodDescribe = getMethodDescribe("getSysConfigById");
        LogUtil.njcnDebug(log, "{}", methodDescribe, id);
        Config config = iConfigService.getById(id);
        if (Objects.isNull(config)) {
            return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.NO_DATA, null, methodDescribe);
        } else {
            return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, config, methodDescribe);
        }
    }


    @OperateInfo(info = LogEnum.SYSTEM_COMMON)
    @GetMapping("/updateSysConfigById")
    @ApiOperation("根据配置Id更改(激活)系统状态")
    @ApiImplicitParam(name = "id", value = "参数id", required = true)
    public HttpResult<Config> updateSysConfigById(@RequestParam("id") String id) {
        String methodDescribe = getMethodDescribe("updateSysConfigById");
        LogUtil.njcnDebug(log, "{}", methodDescribe, id);
        Config config = iConfigService.getById(id);
        if (!Objects.isNull(config)) {
            iConfigService.update( new UpdateWrapper<Config>().eq("sys_config.State", DataStateEnum.ENABLE.getCode())
                    .set("sys_config.State", DataStateEnum.DELETED.getCode()));
            iConfigService.update( new UpdateWrapper<Config>().eq("sys_config.Id", id)
                    .set("sys_config.State", DataStateEnum.ENABLE.getCode()));
            return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, null, methodDescribe);
        }else {
            return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.ID_NOT_EXIST, null, methodDescribe);
        }
    }


    @OperateInfo(info = LogEnum.SYSTEM_COMMON)
    @GetMapping("/removeSysConfigById")
    @ApiOperation("根据配置Id删除系统配置")
    @ApiImplicitParam(name = "id", value = "参数id", required = true)
    public HttpResult<Config> removeSysConfigById(@RequestParam("id") String id) {
        String methodDescribe = getMethodDescribe("removeSysConfigById");
        LogUtil.njcnDebug(log, "{}", methodDescribe, id);
        int count = iConfigService.count(new LambdaQueryWrapper<Config>()
                .eq(Config::getState, DataStateEnum.ENABLE.getCode())
                .ne(Config::getId, id));
        if(count==0){
            //不可更改当前激活状态,必须保留一个激活系统
            throw new BusinessException(SystemResponseEnum.ACTIVATED_STATE);
        }
        boolean res = iConfigService.removeById(id);
        if (res) {
            return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, null, methodDescribe);
        } else {
            return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.ID_NOT_EXIST, null, methodDescribe);
        }
    }


    @OperateInfo(info = LogEnum.SYSTEM_COMMON, operateType = OperateType.ADD)
    @PostMapping("/addSysConfig")
    @ApiOperation("新增系统配置")
    @ApiImplicitParam(name = "configParam", value = "新增配置实体", required = true)
    public HttpResult<Object> addSysConfig(@RequestBody @Validated ConfigParam configParam) {
        String methodDescribe = getMethodDescribe("addSysConfig");
        LogUtil.njcnDebug(log, "{}", methodDescribe, configParam);
        boolean res = iConfigService.addSysConfig(configParam);
        if (res) {
            return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, null, methodDescribe);
        } else {
            throw new BusinessException(CommonResponseEnum.FAIL);
        }
    }


    @OperateInfo(info = LogEnum.SYSTEM_COMMON, operateType = OperateType.UPDATE)
    @PostMapping("/updateSysConfig")
    @ApiOperation("修改系统配置")
    @ApiImplicitParam(name = "configUpdateParam", value = "更新配置实体", required = true)
    public HttpResult<Object> updateSysConfig(@RequestBody @Validated ConfigParam.ConfigUpdateParam configUpdateParam) {
        String methodDescribe = getMethodDescribe("updateSysConfig");
        LogUtil.njcnDebug(log, "{}", methodDescribe, configUpdateParam);
        boolean res = iConfigService.updateSysConfig(configUpdateParam);
        if (res) {
            return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, null, methodDescribe);
        } else {
            throw new BusinessException(CommonResponseEnum.FAIL);
        }
    }



    @OperateInfo(info = LogEnum.SYSTEM_COMMON)
    @GetMapping("/系统扩容操作")
    @ApiOperation("系统扩容操作")
    public HttpResult<Object> addMemory(@RequestParam("size")Integer sizeInMB) {
        String methodDescribe = getMethodDescribe("addMemory");

        try {
            // 将MB转换为字节
            long sizeInBytes = sizeInMB * 1024 * 1024;

            // 分配一个足够大的byte数组
            byte[] memory = new byte[(int) sizeInBytes];

            // 为了确保JVM不会优化掉这个内存分配（因为它可能认为这个变量未使用），
            // 我们可以对数组进行简单的操作，比如填充数据
            for (int i = 0; i < memory.length; i++) {
                // 简单的数据填充
                memory[i] = (byte) (i % 256);
            }

            // 实际上，你可能不需要对数组进行填充，因为仅仅是分配就足以占用内存。
            // 但填充可以确保内存被实际使用，而不是被JVM优化掉。

            // 注意：这里有一个int类型的限制，因为数组长度是int类型。
            // 如果你需要分配超过Integer.MAX_VALUE字节的内存，你将需要找到其他方法（比如使用多个数组）

            System.out.println("Allocated approximately " + sizeInMB + " MB of memory.");

            // 为了让效果更明显，你可以尝试保持这个引用，或者让这个方法运行足够长的时间
            // 以便你可以观察JVM的行为（比如，使用jconsole或jvisualvm等工具）
            // 注意：在实际应用中，你应该在不再需要时释放这个引用，以避免内存泄漏。

        } catch (OutOfMemoryError e) {
            System.err.println("Failed to allocate memory: " + e.getMessage());
        }
        return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, null, methodDescribe);
    }

}

