package com.bocloud.ims.service.resource.sangfor;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.bocloud.cmp.driver.compute.SangforGroupServerDriver;
import com.bocloud.cmp.model.sangfor.SangForServerGroupModel;
import com.bocloud.cmp.model.sangfor.SangforGroupModel;
import com.bocloud.common.model.*;
import com.bocloud.common.utils.Common;
import com.bocloud.common.utils.GridHelper;
import com.bocloud.ims.entity.SangforServerGroupSim;
import com.bocloud.ims.entity.resource.CloudServer;
import com.bocloud.ims.entity.resource.CloudVendor;
import com.bocloud.ims.entity.resource.SangforServerGroup;
import com.bocloud.ims.interfaces.resource.sangfor.SangforAzService;
import com.bocloud.ims.interfaces.resource.sangfor.SangforGroupServerService;
import com.bocloud.ims.repository.resource.CloudServerRepository;
import com.bocloud.ims.repository.resource.CloudVendorRepository;
import com.bocloud.ims.repository.resource.SangforServerGroupRepository;
import com.google.common.collect.Maps;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;

import java.util.*;
import java.util.stream.Collectors;

@Service("sangforGroupServerService")
public class SangforGroupServerServiceImpl implements SangforGroupServerService {
    private static Logger logger = LoggerFactory.getLogger(SangforGroupServerServiceImpl.class);

    @Autowired
    private SangforServerGroupRepository serverGroupRepository;
    @Autowired
    private SangforGroupServerDriver groupServerDriver;
    @Autowired
    private CloudVendorRepository cloudVendorRepository;
    @Autowired
    private SangforAzService sangforAzService;
    @Autowired
    private CloudServerRepository cloudServerRepository;

    @Override
    public BocloudResult<GridBean<SangforServerGroup>> list(Pager pager, RequestContext context) {
        List<SangforServerGroup> list;
        int total;
        GridBean gridBean;
        try {
            List<Param> params = Optional.ofNullable(pager.getParams()).orElse(new ArrayList<>());
            Boolean simple = pager.getSimple();

            Integer page = 1;
            Integer rows = Integer.MAX_VALUE;
            Map<String, String> sorter = new LinkedHashMap<>();
            pager.setSorter(sorter);

            sorter.put("azId", Common.ZERO);
            sorter.put("parentId", Common.ZERO);
            sorter.put("name", Common.ZERO);

            Long vendorId = null;
            for (Param param : params) {
                Map<String, Object> paramMap = param.getParam();
                if (paramMap.containsKey("vendorId")) {
                    vendorId = Long.valueOf(String.valueOf(paramMap.get("vendorId")));
                }
            }

            CloudVendor vendor = null;
            if (vendorId != null) {
                vendor = cloudVendorRepository.listById(vendorId);
            }

            List<SimpleBean> beans;

            if (simple) {
                total = serverGroupRepository.stCount(params);
                beans = serverGroupRepository.list(params, sorter);
                gridBean = new GridBean(1, 1, total, beans);
            } else {
                if (vendor != null && vendor.getVersion().equals("6.8")) {
                    list = serverGroupRepository.stList(page, rows, params, sorter);
                    List<SangforServerGroup> nodeList = convertToCascading(list, "");
                    list = nodeList;
                    total = list.size();
                } else {
                    total = serverGroupRepository.stCount(params);
                    list = serverGroupRepository.stList(page, rows, params, sorter);
                }
                gridBean = GridHelper.getBean(page, rows, total, list);

                Map<String, String> allAzUuidNameMap = sangforAzService.getAllAzUuidNameMap();
                String azUuid, azName;
                for (SangforServerGroup sg : list) {
                    azUuid = sg.getAzId();
                    if (StringUtils.isNotEmpty(azUuid)) {
                        azName = allAzUuidNameMap.get(azUuid);
                        if (StringUtils.isNotEmpty(azName)) {
                            sg.setAzName(azName);
                        }
                    }
                }
            }

            return new BocloudResult<>(true, gridBean, "查询成功");
        } catch (Exception e) {
            return new BocloudResult<>(false, "查询成功");
        }
    }

    @Override
    public BocloudResult<GridBean<SangforServerGroupSim>> listGroup(Pager pager, RequestContext context) {
        List<SangforServerGroup> list;
        int total;
        GridBean gridBean;
        try {
            List<Param> params = Optional.ofNullable(pager.getParams()).orElse(new ArrayList<>());
            Map<String, String> sorter = Optional.ofNullable(pager.getSorter()).orElse(Maps.newLinkedHashMap());
            if (sorter.getClass().equals(HashMap.class)) {
                sorter = new LinkedHashMap<>(sorter);
                pager.setSorter(sorter);
            }

            sorter.put("azId", Common.ZERO);
            sorter.put("parentId", Common.ZERO);
            sorter.put("name", Common.ZERO);

            Integer page = pager.getPage();
            Integer rows = pager.getRows();

            list = serverGroupRepository.stList(page, rows, params, sorter);
            String jsonDate = JSON.toJSON(list).toString();

            JSONArray jsonArray = JSONArray.parseArray(jsonDate);
            List<SangforServerGroupSim> nodeList = convertToSimCascading(jsonArray, "");
            total = nodeList.size();
            gridBean = GridHelper.getBean(page, rows, total, nodeList);

            return new BocloudResult<>(true, gridBean, "查询成功");
        } catch (Exception e) {
            return new BocloudResult<>(false, "查询成功");
        }
    }

    private static List<SangforServerGroup> convertToCascading(List<SangforServerGroup> groupList, String parentId) {
        List<SangforServerGroup> nodeList = new ArrayList<>();

        for (int i = 0; i < groupList.size(); i++) {
            SangforServerGroup group = groupList.get(i);
            Long id = group.getId();
            String uuid = group.getUuid();
            String currentParentId = group.getParentId();
            String name = group.getName();
            String azName = group.getAzName();
            String azId = group.getAzId();
            String projectName = group.getProjectName();
            String projectId = group.getProjectId();
            Long creatorId = group.getCreatorId();
            Date gmtCreate = group.getGmtCreate();
            if (currentParentId == null) {
                currentParentId = "";
            }
            if (Objects.equals(currentParentId, parentId)) {
                SangforServerGroup node = new SangforServerGroup(id, uuid, currentParentId, name, creatorId, azName, azId, projectName, projectId, gmtCreate);
                List<SangforServerGroup> children = convertToCascading(groupList, uuid);
                node.setChildren(children.isEmpty() ? null : children);
                nodeList.add(node);
            }
        }
        return nodeList;
    }

    private static List<SangforServerGroupSim> convertToSimCascading(JSONArray jsonArray, String parentId) {
        List<SangforServerGroupSim> nodeList = new ArrayList<>();
        for (int i = 0; i < jsonArray.size(); i++) {
            JSONObject jsonObject = jsonArray.getJSONObject(i);
            String uuid = jsonObject.getString("uuid");//云主机uuid
            String currentParentId = jsonObject.getString("parentId");//父级id
            String name = jsonObject.getString("name");//云主机分组名称
            if (currentParentId == null) {
                currentParentId = "";
            }
            if (parentId.equals(currentParentId)) {
                SangforServerGroupSim node = new SangforServerGroupSim(name, uuid);
                List<SangforServerGroupSim> children = convertToSimCascading(jsonArray, uuid);
                node.setChildren(children.isEmpty() ? null : children);
                nodeList.add(node);
            }
        }
        return nodeList;
    }


    @Override
    public BocloudResult<GridBean<SangforServerGroup>> create(Pager pager, RequestContext context, SangforServerGroup serverGroup) {
        try {
            if (Objects.isNull(serverGroup)) {
                return new BocloudResult<>(false, "参数为空");
            }
            logger.info("前端传过来的参数:{}", serverGroup);
            CloudVendor vendor = cloudVendorRepository.query(serverGroup.getVendorId());
            Assert.notNull(vendor, "该云平台不存在");
            SangforGroupModel model = new SangforGroupModel();
            model.setName(serverGroup.getName());
            model.setAzId(serverGroup.getAzId());
            model.setProjectId(serverGroup.getProjectId());
            model.setParentId(serverGroup.getParentId());
            BocloudResult result = groupServerDriver.create(vendor.getUuid(), model);
            if (result.isSuccess()) {
                List<SangForServerGroupModel> serverGroupModels = JSON.parseArray(JSON.toJSON(result.getData()).toString(), SangForServerGroupModel.class);
                for (SangForServerGroupModel groupModel : serverGroupModels) {
                    SangforServerGroup group = new SangforServerGroup();
                    group.setUuid(groupModel.getId());
                    group.setName(groupModel.getName());
                    group.setCloudType(groupModel.getCloud_type());
                    group.setVendorId(vendor.getId());
                    group.setParentId(groupModel.getParent_id());
                    group.setPlatformType(groupModel.getPlatform_type());
                    group.setProjectId(groupModel.getProject_id());
                    group.setGroupType(groupModel.getGroup_type());
                    group.setAzId(groupModel.getAz_id());
                    group.setCreatorId(context.getTarget());
                    group.setGmtCreate(new Date());
                    serverGroupRepository.save(group);
                }
                return new BocloudResult<>(true, "创建虚拟机分组成功");
            } else {

                return new BocloudResult<>(false, result.getMessage());
            }
        } catch (Exception e) {
            e.printStackTrace();
            return new BocloudResult<>(false, e.getMessage());
        }
    }

    @Override
    public BocloudResult<GridBean<SangforServerGroup>> update(Pager pager, RequestContext context, Long id, SangforServerGroup serverGroup) {
        try {
            SangforServerGroup group = serverGroupRepository.listById(id);
            Assert.notNull(group, "虚拟机分组不存在");
            CloudVendor vendor = cloudVendorRepository.query(group.getVendorId());
            Assert.notNull(vendor, "该平台不存在");

            if (StringUtils.isNotEmpty(serverGroup.getName())) {
                // 分组编辑
                SangforGroupModel model = new SangforGroupModel();
                model.setName(serverGroup.getName());
                model.setGroupId(group.getUuid());
                BocloudResult result = groupServerDriver.update(vendor.getUuid(), model);
                if (result.isSuccess()) {
                    List<SangForServerGroupModel> serverGroupModels = JSON.parseArray(JSON.toJSON(result.getData()).toString(), SangForServerGroupModel.class);
                    for (SangForServerGroupModel groupModel : serverGroupModels) {
                        SangforServerGroup sangforServerGroup = new SangforServerGroup();
                        sangforServerGroup.setId(id);
                        sangforServerGroup.setDeleted(false);
                        sangforServerGroup.setGmtModify(new Date());
                        sangforServerGroup.setVendorId(vendor.getId());
                        sangforServerGroup.setUuid(groupModel.getId());
                        sangforServerGroup.setName(groupModel.getName());
                        sangforServerGroup.setAzId(groupModel.getAz_id());
                        sangforServerGroup.setCreatorId(context.getTarget());
                        sangforServerGroup.setGmtCreate(group.getGmtCreate());
                        sangforServerGroup.setParentId(groupModel.getParent_id());
                        sangforServerGroup.setCloudType(groupModel.getCloud_type());
                        sangforServerGroup.setProjectId(groupModel.getProject_id());
                        sangforServerGroup.setGroupType(groupModel.getGroup_type());
                        sangforServerGroup.setPlatformType(groupModel.getPlatform_type());
                        serverGroupRepository.update(sangforServerGroup);
                    }
                    return new BocloudResult<>(true, "更新成功");
                } else {
                    return new BocloudResult<>(false, result.getMessage());
                }
            }else {
                // 设置虚拟机的分组
                SangforGroupModel model = new SangforGroupModel();
                model.setServerIds(serverGroup.getServerIds());
                model.setGroupId(group.getUuid());
                BocloudResult result = groupServerDriver.update(vendor.getUuid(), model);
                if (result.isSuccess()) {
                    List<String> instanceIds = serverGroup.getServerIds().stream()
                            .map(Object::toString)
                            .collect(Collectors.toList());

                    List<CloudServer> cloudServers = cloudServerRepository.listByInstanceId(instanceIds);
                    for (CloudServer vm : cloudServers) {
                        vm.setGroupId(group.getUuid());
                        vm.setGroupName(group.getName());
                        vm.setMenderId(context.getTarget());
                        vm.setGmtModify(new Date());
                        cloudServerRepository.update(vm);
                    }
                    return new BocloudResult<>(true, "更新成功");
                } else {
                    return new BocloudResult<>(false, result.getMessage());
                }

            }
        } catch (Exception e) {
            return new BocloudResult<>(false, "更新失败");
        }
    }

    @Override
    public BocloudResult<GridBean<SangforServerGroup>> delete(Pager pager, RequestContext context, Long id) {
        try {
            SangforServerGroup group = serverGroupRepository.listById(id);
            Assert.notNull(group, "虚拟机分组不存在");
            CloudVendor vendor = cloudVendorRepository.query(group.getVendorId());
            Assert.notNull(vendor, "该平台不存在");
            SangforServerGroup serverGroup = serverGroupRepository.listByParentId(vendor.getId(), group.getUuid());
            if (serverGroup != null) {
                return new BocloudResult<>(false, "该分组下有子分组,请先删除子分组");
            }
            BocloudResult result = groupServerDriver.delete(vendor.getUuid(), group.getUuid());
            if (result.isSuccess()) {
                serverGroupRepository.removeById(group.getId());
                return new BocloudResult<>(true, "删除" + "【" + group.getName() + "】" + "成功");
            } else {
                return new BocloudResult<>(false, result.getMessage());
            }
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            return new BocloudResult<>(false, "删除失败:" + e.getMessage());
        }
    }
}
