package com.skr.mdm.api.admin.service.impl;

import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.asymmetric.KeyType;
import cn.hutool.crypto.asymmetric.SM2;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.skr.mdm.api.admin.service.AdminPermissionService;
import com.skr.mdm.bean.bo.RolePermissionBO;
import com.skr.mdm.dao.AuCompanyDao;
import com.skr.mdm.dao.AuRolePermissionDao;
import com.skr.mdm.entity.AuCompanyDO;
import com.skr.mdm.enums.ResultCodeEnum;
import com.skr.mdm.license.LicenseVerify;
import com.skr.mdm.result.ResponseResult;
import com.skr.mdm.util.SmUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * @author nfq
 * @date 2020/9/11 10:13
 */
@Service
@Slf4j
public class AdminPermissionServiceImpl implements AdminPermissionService {

    @Value("${mdm.license.company}")
    private Boolean companyLicense;

    @Autowired
    private AuCompanyDao companyDao;
    @Autowired
    private AuRolePermissionDao rolePermissionDao;

    @Override
    public ResponseResult menuTree(Integer companyId, Integer roleId) {
        AuCompanyDO companyDO = companyDao.selectById(companyId);
        if (Objects.isNull(companyDO)) {
            return ResponseResult.success();
        }
        if (companyLicense) {
            if (StringUtils.isNotBlank(companyDO.getExpirationTime())) {
                SM2 sm2 = SmUtils.sm2();
                String expirationTime = StrUtil.utf8Str(sm2.decryptFromBcd(companyDO.getExpirationTime(), KeyType.PrivateKey));
                if (System.currentTimeMillis() > Long.valueOf(expirationTime)) {
                    // 公司授权过期
                    return ResponseResult.failure(ResultCodeEnum.AUTHORIZATION_EXPIRES);
                }
            }
        } else {
            LicenseVerify licenseVerify = new LicenseVerify();
            // 校验证书是否有效
            boolean verifyResult = licenseVerify.verify();
            if (!verifyResult) {
                return ResponseResult.failure(ResultCodeEnum.AUTHORIZATION_EXPIRES.getCode(), "您的证书无效，请核查服务器是否取得授权或重新申请证书！");
            }
        }
        return ResponseResult.success(tree(roleId, companyDO.getFunctionScopeId()));
    }

    @Override
    public ResponseResult getGaodeSid(Integer companyId) {
        AuCompanyDO companyDO = companyDao.selectById(companyId);
        return ResponseResult.success(companyDO.getSid());
    }

    public List<Map<String, Object>> tree(Integer roleId, Integer functionScopeId) {
        List<RolePermissionBO> rolePermissionBOList = rolePermissionDao.listPermissionByRoleId(roleId, functionScopeId);
        if (CollectionUtils.isEmpty(rolePermissionBOList)) {
            return Collections.emptyList();
        }
        return children(0, rolePermissionBOList);
    }

    private List<Map<String, Object>> children(Integer parentId, List<RolePermissionBO> rolePermissionBOList) {
        List<Map<String, Object>> list = Lists.newArrayListWithCapacity(64);
        if (CollectionUtils.isNotEmpty(rolePermissionBOList)) {
            Map<String, Object> map;
            for (RolePermissionBO rolePermissionBO : rolePermissionBOList) {
                if (rolePermissionBO.getParentId().equals(parentId)) {
                    map = Maps.newHashMapWithExpectedSize(5);
                    map.put("name", rolePermissionBO.getName());
                    map.put("value", rolePermissionBO.getId());
                    map.put("percode", rolePermissionBO.getPercode());
                    map.put("checked", true);
                    map.put("children", children(rolePermissionBO.getId(), rolePermissionBOList));
                    list.add(map);
                }
            }
        }
        return list;
    }
}
