package com.pingcap.syngmail.thread;

import cn.authing.core.mgmt.ManagementClient;
import cn.authing.core.types.OrgNode;
import cn.authing.core.types.User;
import com.google.api.services.admin.directory.Directory;
import com.google.api.services.admin.directory.model.Groups;
import com.mysql.cj.util.StringUtils;
import com.pingcap.syngmail.common.Common;
import com.pingcap.syngmail.util.CommonUtils;
import com.pingcap.syngmail.util.GoogleApiUtils;
import lombok.extern.slf4j.Slf4j;

import java.io.IOException;
import java.util.*;
import java.util.concurrent.Callable;

/**
 * @author zhuxiaopeng
 * @version 1.0.0
 * @Description 人员和部门与google比对创建新部门，员工退出google上与authing不匹配的组
 * @createTime 2022年04月20日 17:06:00
 */
@Slf4j
public class AuthingCampare implements Callable {

    private ManagementClient client;

    private Directory service;

    public AuthingCampare(ManagementClient client, Directory service) {
        this.client = client;
        this.service = service;
    }

    private int tag = 1;

    @Override
    public Object call() {
        try {
            List<OrgNode> orgNodeList = client.org().exportAll().execute();

            //检查每个部门和员工是否在google中存在
            Map<String, Map<String, Boolean>> employeeToGroups = new HashMap<>();
            for (OrgNode orgNode : orgNodeList) {
                List<String> list = new ArrayList<>();
                list.add("");
                dfs(orgNode, service,list, "", employeeToGroups);
            }

            //员工所在部门，和google中对应的个人比对
            Set<Map.Entry<String, Map<String, Boolean>>> entries = employeeToGroups.entrySet();
            for (Map.Entry<String, Map<String, Boolean>> entry : entries) {
                String userMail = entry.getKey();
                Map<String, Boolean> authingGroups = entry.getValue();
                Groups execute = service.groups().list().setUserKey(userMail).execute();
                List<com.google.api.services.admin.directory.model.Group> googleGroups = execute.getGroups();
                for (com.google.api.services.admin.directory.model.Group googleGroup : googleGroups) {
                    if (authingGroups.containsKey(googleGroup.getEmail())) {
                        continue;
                    }
                    //只对本服务创建的google组做退出，不修改原先的组
                    if (googleGroup.getName().startsWith(Common.PRE)) {
                        GoogleApiUtils.deleteMember(service, userMail,"",googleGroup.getEmail());
                    }
                }
            }
        } catch (IOException e) {
            log.error(e.getMessage());
        }
        return null;
    }
    void dfs(OrgNode node, Directory service,List<String> preNodes, String preDepartment, Map<String, Map<String, Boolean>> employeeToGroups) {
        List<OrgNode> children = node.getChildren();
        //当前部门是否在google中存在
        String groupMailName = GoogleApiUtils.checkGroup(preDepartment, service,node.getName(),node.getId());
        if (StringUtils.isNullOrEmpty(groupMailName)) {
            return;
        }

        List<User> users = node.getUsers();
        for (User user : users) {

            System.out.println("tag="+(tag++)+user.getEmail());
            String email = user.getEmail();
            for (int i = 1; i < preNodes.size(); i++) {
                String groupMail = CommonUtils.getDepartmentMail(preNodes.get(i - 1), preNodes.get(i));
                if (StringUtils.isNullOrEmpty(groupMail)) {
                    continue;
                }
                if (!GoogleApiUtils.isExistsMember(service, email, groupMail)) {
                    GoogleApiUtils.addMember(service, email, groupMail);
                }
            }

            //员工在google中不再当前组，则加入组
            if (!GoogleApiUtils.isExistsMember(service, email, groupMailName)) {
                GoogleApiUtils.addMember(service, email, groupMailName);
            }

            Map<String, Boolean> groups = employeeToGroups.getOrDefault(user.getEmail(), null);
            if (groups == null) {
                groups = new HashMap<>();
            }
            groups.put(groupMailName, true);
            employeeToGroups.put(user.getEmail(), groups);
        }

        preDepartment = node.getName();
        if (children != null) {
            for (OrgNode child : children) {
                preNodes.add(node.getName());
                dfs(child, service,preNodes, preDepartment, employeeToGroups);
                preNodes.remove(preNodes.size()-1);
                String childMail = CommonUtils.getDepartmentMail(preDepartment, child.getName());
                if (!StringUtils.isNullOrEmpty(groupMailName)) {
                    GoogleApiUtils.addMember(service, childMail, groupMailName);
                }
            }
        }
    }
}
