package com.engine.salary.service.auth;

import com.engine.core.impl.Service;
import com.engine.salary.constant.SalaryDefaultTenantConstant;
import com.engine.salary.entity.auth.dto.AuthOptDTO;
import com.engine.salary.entity.auth.param.AuthOptSaveParam;
import com.engine.salary.entity.auth.po.AuthOptPO;
import com.engine.salary.entity.auth.po.AuthRolePO;
import com.engine.salary.exception.SalaryRunTimeException;
import com.engine.salary.mapper.auth.AuthOptMapper;
import com.engine.salary.mapper.auth.AuthRoleMapper;
import com.engine.salary.util.SalaryEntityUtil;
import com.engine.salary.util.db.IdGenerator;
import com.engine.salary.util.db.MapperProxyFactory;
import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.security.AnyTypePermission;
import weaver.general.GCONST;

import java.io.File;
import java.util.*;

public class AuthOptServiceImpl extends Service implements AuthOptService {



    private AuthOptMapper getAuthOptMapper() {
        return MapperProxyFactory.getProxy(AuthOptMapper.class);
    }

    private AuthRoleMapper getAuthRoleMapper() {
        return MapperProxyFactory.getProxy(AuthRoleMapper.class);
    }


    @Override
    public AuthOptDTO optTree(Long roleId) {
        List<AuthOptPO> authOptPOS = getAuthOptMapper().listSome(AuthOptPO.builder().roleId(roleId).build());
        Map<String, Set<String>> pageOpts = SalaryEntityUtil.group2Map(authOptPOS, AuthOptPO::getPage, AuthOptPO::getOpt);
        XStream xStream = new XStream();
        String resource = GCONST.getRootPath() + "WEB-INF" + File.separatorChar + "salaryoptconfig.xml";
//        File file = new File("H:\\code\\salary\\resource\\WEB-INF\\salaryoptconfig.xml");
        File file = new File(resource);

        xStream.addPermission(AnyTypePermission.ANY);
        xStream.processAnnotations(AuthOptDTO.class);
        AuthOptDTO dto = (AuthOptDTO)xStream.fromXML(file);

        dto.getModules().forEach(module -> {
            module.getPages().forEach(page -> {
                Set<String> opts = pageOpts.getOrDefault(page.getKey(),new HashSet<>());
                page.getOpts().forEach(opt -> {
                    if(opts.contains(opt.getKey())){
                        opt.setAble(true);
                    }
                });
            });
        });

        return dto;
    }

    @Override
    public void save(AuthOptSaveParam param) {
        Date now = new Date();
        Long roleId = param.getRoleId();
        AuthRolePO rolePO = getAuthRoleMapper().getById(roleId);
        if (rolePO == null) {
            throw new SalaryRunTimeException("角色不存在！");
        }

        getAuthOptMapper().deleteByRoleId(roleId);

        param.getOpts().forEach(opt -> {
            AuthOptPO po = AuthOptPO.builder()
                    .id(IdGenerator.generate())
                    .roleId(roleId)
                    .page(opt.getPage())
                    .opt(opt.getOpt())
                    .creator((long) user.getUID())
                    .createTime(now)
                    .updateTime(now)
                    .deleteType(0)
                    .tenantKey(SalaryDefaultTenantConstant.DEFAULT_TENANT_KEY)
                    .build();
            getAuthOptMapper().insertIgnoreNull(po);
        });
    }

    @Override
    public void deleteByRoleId(Long roleId) {
        getAuthOptMapper().deleteByRoleId(roleId);
    }

    @Override
    public List<AuthOptPO> listOpts(Long roleId) {
       return getAuthOptMapper().listSome(AuthOptPO.builder().roleId(roleId).build());
    }
}
