package com.bocloud.ims.service.transporter.vendor;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Component;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.bocloud.cmp.entity.enums.BocloudStatus;
import com.bocloud.cmp.entity.enums.ResourceCategory;
import com.bocloud.cmp.model.FlavorModel;
import com.bocloud.cmp.model.ImageModel;
import com.bocloud.cmp.model.KeypairModel;
import com.bocloud.cmp.model.KingCloudSyncModel;
import com.bocloud.cmp.model.RegionModel;
import com.bocloud.cmp.model.SecurityGroupModel;
import com.bocloud.cmp.model.SecurityGroupRuleModel;
import com.bocloud.cmp.model.ServerModel;
import com.bocloud.cmp.model.SubnetModel;
import com.bocloud.cmp.model.VpcModel;
import com.bocloud.cmp.model.ZoneModel;
import com.bocloud.common.enums.OSCategory;
import com.bocloud.common.enums.ResourceCatalog;
import com.bocloud.common.model.BocloudResult;
import com.bocloud.common.model.Result;
import com.bocloud.common.utils.IDFactory;
import com.bocloud.common.utils.ListTool;
import com.bocloud.ims.entity.resource.CloudServer;
import com.bocloud.ims.entity.resource.CloudVendor;
import com.bocloud.ims.entity.resource.Flavor;
import com.bocloud.ims.entity.resource.Image;
import com.bocloud.ims.entity.resource.Keypair;
import com.bocloud.ims.entity.resource.Region;
import com.bocloud.ims.entity.resource.Resource;
import com.bocloud.ims.entity.resource.SecurityGroup;
import com.bocloud.ims.entity.resource.SecurityGroupRule;
import com.bocloud.ims.entity.resource.ServerSgroup;
import com.bocloud.ims.entity.resource.Subnet;
import com.bocloud.ims.entity.resource.Vpc;
import com.bocloud.ims.entity.resource.Zone;
import com.bocloud.ims.service.model.cmdb.CmdbInfo;
import com.bocloud.ims.service.transporter.AbstractTransporter;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;

/**
 * 金山同步
 *
 * @author ymh
 * @时间 2019年9月18日
 */
@Component
public class KingCloudTransporter extends AbstractTransporter {

    private static Logger logger = LoggerFactory.getLogger(KingCloudTransporter.class);

    @Override
    public Result transport(CloudVendor vendor, Long operator) {
    	return this.syncCloudResource(vendor, operator);
    }
    
    @Override
    public BocloudResult process(CloudVendor vendor, Object data, Region region, Long userId, List<CmdbInfo> infos) {
        try {
            if (null != data) {
                if (cloudServerRepository.hasBuilding(vendor.getId())) {
                    return new BocloudResult(false, "该平台下有云主机正在创建，请稍后进行同步操作");
                }

                Long vendorId = vendor.getId();
                String content = JSONObject.toJSONString(data);
                KingCloudSyncModel model = JSONObject.parseObject(content, KingCloudSyncModel.class);

                // 同步区域
                logger.info("Starting sync region......" + region.getRegionId());
                this.syncRegions(model.getRegionModels(), vendorId, userId, region.getRegionId());
                logger.info("End sync region......");

                // 同步密钥
                logger.info("Starting sync keyPairs.....");
                this.syncKeyPairs(model.getKeypairModels(), vendor.getId(), userId, region.getRegionId());
                logger.info("End sync keyPairs......");

                // 同步vpc
                logger.info("Starting sync vpc......");
                this.syncVpc(model.getVpcModels(), vendor.getId(), userId, region.getRegionId());
                logger.info("End sync vpc......");

                // 同步安全组
                logger.info("Starting sync security group ... ");
                this.syncSecurityGroup(model.getSecurityGroupModels(), vendor, userId, region.getRegionId());
                logger.info("End sync security group ......");

                // 同步规格
                logger.info("Starting sync flavor......");
                this.syncFlavor(model.getFlavorModels(), vendorId, userId, region.getRegionId());
                logger.info("End sync flavor......");

                // 同步镜像
                Map<String, Image> imageMap = Maps.newHashMap();
                logger.info("Starting sync image......");
                this.syncImage(model.getImageModels(), vendorId, region.getRegionId(), userId, vendor.getType(),
                        imageMap);
                logger.info("End sync image......");

                // 同步云主机
                logger.info("Starting sync server......");
                Map<String, CloudServer> serverMap = new HashMap<>();
                this.syncServer(model.getServerModels(), vendor, userId, region, vendor.getType(), serverMap);
                Map<String, CloudServer> sMap = new HashMap<>();
                List<CloudServer> serverByVid = cloudServerRepository.listByVid(vendor.getId(), region.getRegionId());
                for (CloudServer cloudServer : serverByVid) {
                    sMap.put(cloudServer.getInstanceId(), cloudServer);
                }
                logger.info("End sync server......");
            }
            return new BocloudResult(true, "云平台【" + vendor.getName() + "】平台数据同步成功");
        } catch (Exception e) {
            logger.error("Get error message:", e);
            return new BocloudResult(false, "云平台【" + vendor.getName() + "】平台数据同步失败:" + e.getMessage());
        }
    }

    private void syncKeyPairs(List<KeypairModel> models, Long vendorId, Long userId, String regionId) throws Exception {
        if (ListTool.isEmpty(models)) {
            keypairRepository.removeByVid(vendorId, userId);
            return;
        }
        List<Keypair> keypairs = keypairRepository.listByVid(vendorId);
        Map<String, Keypair> keypairMap = Maps.newHashMap();
        for (Keypair keypair : keypairs) {
            keypairMap.put(keypair.getFingerprint(), keypair);
        }
        for (KeypairModel model : models) {
            Keypair keypair = new Keypair();
            if (keypairMap.containsKey(model.getFingerprint())) {
                keypair = keypairMap.get(model.getFingerprint());
                BeanUtils.copyProperties(model, keypair);
                model.setGmtCreate(keypair.getGmtCreate());
                model.setUserUuid(keypair.getUserUuid());
                keypair.setMenderId(userId);
                keypair.setGmtModify(new Date());
                keypairRepository.update(keypair);
                keypairMap.remove(keypair.getFingerprint());
                continue;
            }
            BeanUtils.copyProperties(model, keypair);
            keypair.setCreatorId(userId);
            keypair.setGmtCreate(model.getGmtCreate());
            keypair.setVendorId(vendorId);
            keypair.setTenantId(0L);
            keypair.setProjectId(0L);
            keypairRepository.save(keypair);
            keypairMap.remove(model.getFingerprint());
        }
        for (Map.Entry<String, Keypair> entry : keypairMap.entrySet()) {
            keypairRepository.remove(entry.getValue().getId(), userId);
        }
    }

    /**
     * 同步安全组
     *
     * @param models
     * @param vendor
     * @param userId
     * @throws Exception
     */
    private void syncSecurityGroup(List<SecurityGroupModel> models, CloudVendor vendor, Long userId, String region)
            throws Exception {
        // 当安全组为空时,删除数据库残留数据
        if (ListTool.isEmpty(models)) {
            securityGroupRepository.removeByVid(vendor.getId(), region, userId);
            return;
        }
        List<SecurityGroup> groups = securityGroupRepository.listByVendorId(vendor.getId(), region, null);
        Map<String, SecurityGroup> groupMap = Maps.newHashMap();
        for (SecurityGroup group : groups) {
            groupMap.put(group.getGroupUuid(), group);
        }
        List<Vpc> vpcs = vpcRepository.list(vendor.getId(), region);
        Map<String, Vpc> vpcMap = Maps.newHashMap();
        for (Vpc vpc : vpcs) {
            vpcMap.put(vpc.getVpcId(), vpc);
        }
        for (SecurityGroupModel model : models) {
            SecurityGroup group = new SecurityGroup();
            if (groupMap.containsKey(model.getGroupUuid())) {
                group = groupMap.get(model.getGroupUuid());
                BeanUtils.copyProperties(model, group);
                group.setMenderId(userId);
                group.setRegionId(region);
                if (vpcMap.containsKey(group.getVpcUuid())) {
                    group.setVpcId(vpcMap.get(group.getVpcUuid()).getId());
                }
                securityGroupRepository.update(group);
                securityGroupRuleRepository.removeBySgId(group.getId(), userId);
                for (SecurityGroupRuleModel securityGroupRuleModel : model.getModels()) {
                    SecurityGroupRule securityGroupRule = new SecurityGroupRule();
                    BeanUtils.copyProperties(securityGroupRuleModel, securityGroupRule);
                    securityGroupRule.setCreatorId(userId);
                    securityGroupRule.setVendorId(vendor.getId());
                    securityGroupRule.setGroupId(group.getId());
                    securityGroupRule.setGroupUuid(group.getGroupUuid());
                    securityGroupRuleRepository.save(securityGroupRule);
                }
                groupMap.remove(model.getGroupUuid());
                continue;
            }
            group = JSONObject.parseObject(JSONObject.toJSONString(model), SecurityGroup.class);
            BeanUtils.copyProperties(model, group);
            group.preSave(userId, userId, vendor.getId(), 0L, 0L);
            group.setRegionId(region);
            if (vpcMap.containsKey(group.getVpcUuid())) {
                group.setVpcId(vpcMap.get(group.getVpcUuid()).getId());
            }
            securityGroupRepository.save(group);
            securityGroupRuleRepository.removeBySgId(group.getId(), userId);
            for (SecurityGroupRuleModel securityGroupRuleModel : model.getModels()) {
                SecurityGroupRule securityGroupRule = new SecurityGroupRule();
                BeanUtils.copyProperties(securityGroupRuleModel, securityGroupRule);
                securityGroupRule.setCreatorId(userId);
                securityGroupRule.setVendorId(vendor.getId());
                securityGroupRule.setGroupId(group.getId());
                securityGroupRule.setGroupUuid(group.getGroupUuid());
                securityGroupRuleRepository.save(securityGroupRule);
            }
        }
        // 删除不存在的安全组
        for (Entry<String, SecurityGroup> entry : groupMap.entrySet()) {
            securityGroupRepository.remove(entry.getValue().getId(), userId);
        }
    }

    /**
     * 同步云主机
     *
     * @param serverModels
     * @param vendor
     * @param userId
     * @param region
     * @param type
     * @param serverMap
     * @throws Exception
     */
    private void syncServer(List<ServerModel> serverModels, CloudVendor vendor, Long userId, Region region, String type,
                            Map<String, CloudServer> serverMap) throws Exception {
        if (ListTool.isEmpty(serverModels)) {
            List<CloudServer> servers = cloudServerRepository.listByVendorId(vendor.getId(), region.getRegionId());
            for (CloudServer server : servers) {
                serverSgroupRepository.removeBySid(server.getId());
                volumeRepository.detachVolumes(server.getId(), userId);
            }
            cloudServerRepository.removeByVid(vendor.getId(), region.getRegionId(), userId);
            // 删除资源表
            resourceRepository.removeByVidReg(vendor.getId(), region.getRegionId(), userId);
            return;
        }
        // 获取平台云主机信息
        List<CloudServer> servers = cloudServerRepository.listByVendorId(vendor.getId(), region.getRegionId());
        Map<String, CloudServer> cloudSeverMap = Maps.newHashMap();
        for (CloudServer server : servers) {
            cloudSeverMap.put(server.getInstanceId(), server);
        }
        // 获取平台安全组信息
        List<SecurityGroup> securityGroups = securityGroupRepository.listByVendorId(vendor.getId(),
                region.getRegionId(), null);
        Map<String, Long> groupMap = Maps.newHashMap();
        for (SecurityGroup group : securityGroups) {
            groupMap.put(group.getName(), group.getId());
        }
        CloudServer vm = null;
        for (ServerModel server : serverModels) {
            Flavor flavor = flavorRepository.getByFlavorUuid(server.getFlavorUuid());
            // 更新已创建的云主机
            if (cloudSeverMap.containsKey(server.getInstanceId())) {
                vm = cloudSeverMap.get(server.getInstanceId());

                String account = vm.getAccount();
                if (StringUtils.isEmpty(account)) {
                    Image image = imageRepository.getByImageUuid(server.getImageUuid());
                    if (null != image) {
                        account = image.getDefaultUser();
                    }
                }
                server.setAccount(account);
                server.setPassword(vm.getPassword());
                BeanUtils.copyProperties(server, vm);

                vm.setOsCategory(server.getOsCategory());
                vm.setOsName(server.getOsName());
                vm.setOsVersion(server.getOsVersion());
                if ("error".equalsIgnoreCase(server.getStatus())) {
                    vm.setStatus(BocloudStatus.Server.EXCEPTION.name());
                } else {
                    vm.setStatus(server.getStatus());
                }

                List<Long> sgIds = null;
                String groups = server.getGroups();
                if (!StringUtils.isEmpty(groups)) {
                    List<String> groupList = JSONArray.parseArray(groups, String.class);
                    if (null != groupList && groupList.size() > 0) {
                        sgIds = new ArrayList<Long>();
                        for (String sgName : groupList) {
                            sgIds.add(groupMap.get(sgName));
                        }
                    }
                }

                vm.setHostId(0L);
                vm.setPassword(server.getPassword());
                vm.setIsTemplate(false);
                vm.setGmtVmCreate(server.getGmtVmCreate());
                vm.setPrivateIps(server.getPrivateIps());
                if (null != flavor) {
                    vm.setCpu(flavor.getCpu());
                    vm.setMemory(flavor.getMemory());
                }
                vm.setRegionId(region.getRegionId());
                vm.setVendorId(vendor.getId());
                cloudServerRepository.update(vm);
                // 更新资源表
                updateResource(vm, vendor, region.getRegionId(), userId);
                cloudSeverMap.remove(vm.getInstanceId());
                // 更新云主机绑定的安全组
                serverSgroupRepository.removeBySid(vm.getId());
                updateSGroup(vm.getId(), JSON.toJSONString(server.getSecurityGroups()), groupMap);
                serverMap.remove(vm.getInstanceId());
                continue;
            }
            vm = new CloudServer();
            BeanUtils.copyProperties(server, vm);
            if ("error".equalsIgnoreCase(server.getStatus())) {
                vm.setStatus(BocloudStatus.Server.EXCEPTION.name());
            } else {
                vm.setStatus(server.getStatus());
            }
            vm.setVendorId(vendor.getId());
            vm.setRegionId(region.getRegionId());
            vm.setIsTemplate(false);
            vm.setResourceId(IDFactory.instance().uuid());
            vm.setVendorType(type);
            vm.setGmtVmCreate(server.getGmtVmCreate());
            vm.setPrivateIps(server.getPrivateIps());
            vm.setMenderId(0L);
            vm.setTenantId(0L);
            vm.setProjectId(0L);
            vm.setOwnerId(0L);

            List<Long> sgIds = null;
            String groups = server.getGroups();
            if (!StringUtils.isEmpty(groups)) {
                List<String> groupList = JSONArray.parseArray(groups, String.class);
                if (null != groupList && groupList.size() > 0) {
                    sgIds = new ArrayList<Long>();
                    for (String sgName : groupList) {
                        sgIds.add(groupMap.get(sgName));
                    }
                }
            }
            vm.setRecycle(false);
            vm.preSave(userId, userId, vendor.getId(), 0L, null, null, 0L, 0L);
            if (StringUtils.isEmpty(vm.getOsCategory())) {
                vm.setOsCategory(OSCategory.LINUX.name());
            }
            String account = vm.getAccount();
            if (StringUtils.isEmpty(account)) {
                Image image = imageRepository.getByImageUuid(vm.getImageUuid());
                if (null != image) {
                    account = image.getDefaultUser();
                }
            }
            server.setAccount(account);
            if (null != flavor) {
                vm.setCpu(flavor.getCpu());
                vm.setMemory(flavor.getMemory());
            }
            cloudServerRepository.save(vm);
            // 更新资源表
            updateResource(vm, vendor, region.getRegionId(), userId);
            serverSgroupRepository.removeBySid(vm.getId());
            updateSGroup(vm.getId(), JSON.toJSONString(server.getSecurityGroups()), groupMap);
        }
        for (Map.Entry<String, CloudServer> entry : cloudSeverMap.entrySet()) {
            CloudServer server = entry.getValue();
            resourceRepository.remove(server.getId(), ResourceCategory.Computer.name(), ResourceCatalog.LOGICAL.name(),
                    userId);
            volumeRepository.detachVolumes(server.getId(), userId);
            serverSgroupRepository.removeBySid(server.getId());
            cloudServerRepository.remove(server.getId(), userId);
        }
    }

    private void updateSGroup(Long serverId, String groups, Map<String, Long> groupMap) throws Exception {
        if (!StringUtils.isEmpty(groups)) {
            List<String> groupList = JSONArray.parseArray(groups, String.class);
            if (null != groupList && groupList.size() > 0) {
                for (String group : groupList) {
                    ServerSgroup serverSgroup = new ServerSgroup(serverId, groupMap.get(group));
                    serverSgroupRepository.save(serverSgroup);
                }
            }
        }
    }

    /**
     * 更新资源表相关信息
     *
     * @param server
     * @param vendor
     * @param userId
     * @throws Exception
     */
    private void updateResource(CloudServer server, CloudVendor vendor, String region, Long userId) throws Exception {
        // 更新资源表
        Resource resource = resourceRepository.query(ResourceCategory.Computer.name(), ResourceCatalog.LOGICAL.name(),
                server.getId());
        // 保存资源
        List<String> ips = Lists.newArrayList();
        if (!StringUtils.isEmpty(server.getPrivateIps())) {
            List<JSONObject> objects = JSONObject.parseArray(server.getPrivateIps(), JSONObject.class);
            for (JSONObject object : objects) {
                ips.add(object.getString("address"));
            }
        }
        if (null != resource) {
            resource.setStatus(server.getStatus());
            resource.setPrivateIps(JSONObject.toJSONString(ips));
            resource.setRegionId(region);
            resource.setMenderId(userId);
            resource.setAccurated(false);
            resource.setAuthed(false);
            resourceRepository.update(resource);
            server.setResource(resource);
        } else {
            resource = new Resource(ResourceCategory.Computer.name(), ResourceCatalog.LOGICAL.name(), server.getId(),
                    null, server.getOsCategory(), vendor.getId());
            resource.preSave(server.getName(), server.getStatus(), userId, 0L, 0L);
            resource.setInventory(JSONObject.toJSONString(server));
            resource.setRegionId(region);
            resource.setPrivateIps(JSONObject.toJSONString(ips));
            resource.setOwnerId(userId);
            resource.setAccurated(false);
            resource.setAuthed(false);
            resourceRepository.save(resource);
            server.setResource(resource);
        }
    }

    /**
     * 同步镜像
     *
     * @param models
     * @param vendorId
     * @param userId
     * @param type
     * @param imageMap
     * @throws Exception
     */
    private void syncImage(List<ImageModel> models, Long vendorId, String regionId, Long userId, String type,
                           Map<String, Image> imageMap) throws Exception {
        if (ListTool.isEmpty(models)) {
            imageRepository.removeByVid(vendorId, regionId, userId);
            return;
        }
        List<Image> images = imageRepository.listByVendorId(vendorId, regionId);
        Map<String, Image> imagesMap = Maps.newConcurrentMap();
        for (Image image : images) {
            if (null != image.getImageUuid()) {
                if (imagesMap.containsKey(image.getImageUuid())) {
                    imageRepository.remove(image.getId(), userId);
                } else {
                    imagesMap.put(image.getImageUuid(), image);
                }
            } else {
                imageRepository.remove(image.getId(), userId);
            }
        }
        for (ImageModel model : models) {
            Image image = new Image();
            // 过滤掉非active的镜像
            if ("ACTIVE".equalsIgnoreCase(model.getStatus())) {
                if (imagesMap.containsKey(model.getImageUuid())) {
                    image = imagesMap.get(model.getImageUuid());
                    BeanUtils.copyProperties(model, image);
                    image.setMenderId(userId);
                    image.setVendorType(type);
                    image.setVendorId(vendorId);
                    image.setRegionId(regionId);
                    image.setDefaultUser(model.getDefaultUser());
                    imageRepository.update(image);
                    imagesMap.remove(model.getImageUuid());
                    continue;
                }
                BeanUtils.copyProperties(model, image);
                image.setVendorId(vendorId);
                image.setCreatorId(userId);
                image.setVendorType(type);
                image.setRegionId(regionId);
                image.setMenderId(userId);
                image.setTenantId(0L);
                image.setProjectId(0L);
                if (!StringUtils.isEmpty(image.getOsCategory())) {
                    image.setOsCategory(image.getOsCategory());
                } else {
                    image.setOsCategory("Linux");
                }
                image.setCatalog("VM");
                imageRepository.save(image);
            } else {
                image = imagesMap.get(model.getImageUuid());
                if (null != image) {
                    imageRepository.remove(image.getId(), userId);
                }
            }
        }
        for (Map.Entry<String, Image> set : imagesMap.entrySet()) {
            imageRepository.remove(set.getValue().getId(), userId);
        }
    }

    /**
     * 同步规格
     *
     * @param models
     * @param vendorId
     * @param userId
     * @throws Exception
     */
    private void syncFlavor(List<FlavorModel> models, Long vendorId, Long userId, String regionId) throws Exception {
        if (ListTool.isEmpty(models)) {
            flavorRepository.removeByVid(vendorId, regionId);
            return;
        }
        List<Flavor> flavors = flavorRepository.listByVendorId(vendorId, regionId);
        Map<String, Flavor> flavorMap = new HashMap<String, Flavor>();
        for (Flavor flavor : flavors) {
            flavorMap.put(flavor.getFlavorUuid(), flavor);
        }
        for (FlavorModel model : models) {
            Flavor flavor = new Flavor();
            if (flavorMap.containsKey(model.getFlavorUuid())) {
                flavor = flavorMap.get(model.getFlavorUuid());
                BeanUtils.copyProperties(model, flavor);
                flavor.setVendorId(vendorId);
                flavor.setRegionId(regionId);
                flavorRepository.update(flavor);
                flavorMap.remove(model.getName());
                continue;
            }
            BeanUtils.copyProperties(model, flavor);
            flavor.setVendorId(vendorId);
            flavor.setRegionId(regionId);
            flavorRepository.save(flavor);
        }
        for (Map.Entry<String, Flavor> entry : flavorMap.entrySet()) {
            flavorRepository.delete(entry.getValue().getId());
        }
    }

    private void syncVpc(List<VpcModel> models, Long vendorId, Long userId, String region) throws Exception {
        if (ListTool.isEmpty(models)) {
            vpcRepository.deleteByVid(vendorId, region, userId);
            return;
        }
        List<Vpc> vpcs = vpcRepository.list(vendorId, region);
        Map<String, Vpc> vpcMap = Maps.newHashMap();
        for (Vpc vpc : vpcs) {
            vpcMap.put(vpc.getVpcId(), vpc);
        }
        for (VpcModel model : models) {
            Vpc vpc = new Vpc();
            if (vpcMap.containsKey(model.getVpcId())) {
                vpc = vpcMap.get(model.getVpcId());
                BeanUtils.copyProperties(model, vpc);
                vpc.setMenderId(userId);
                vpc.setRegionId(region);
                vpcRepository.update(vpc);
                // 同步子网
                this.syncSubnet(model.getSubnetModels(), vendorId, userId, region, vpc.getVpcId());
                vpcMap.remove(model.getVpcId());
                continue;
            }
            BeanUtils.copyProperties(model, vpc);
            vpc.setCreatorId(userId);
            vpc.setVendorId(vendorId);
            vpc.setRegionId(region);
            vpc.setTenantId(0L);
            vpc.setProjectId(0L);
            vpcRepository.save(vpc);
            // 同步子网
            this.syncSubnet(model.getSubnetModels(), vendorId, userId, region, vpc.getVpcId());
            vpcMap.remove(model.getVpcId());
        }
        for (Entry<String, Vpc> entry : vpcMap.entrySet()) {
            vpcRepository.delete(entry.getValue().getId(), userId);
        }
    }

    private void syncSubnet(List<SubnetModel> models, Long vendorId, Long userId, String region, String vpcId)
            throws Exception {
        if (ListTool.isEmpty(models)) {
            subnetRepository.deleteByVpcId(vendorId, vpcId, userId);
            return;
        }
        List<Subnet> subnetList = subnetRepository.listByVpcId(vendorId, vpcId);
        Map<String, Subnet> subnetMap = Maps.newHashMap();
        for (Subnet subnet : subnetList) {
            subnetMap.put(subnet.getSubnetUuid(), subnet);
        }
        for (SubnetModel model : models) {
            Subnet subnet = new Subnet();
            if (subnetMap.containsKey(model.getSubnetUuid())) {
                subnet = subnetMap.get(model.getSubnetUuid());
                BeanUtils.copyProperties(model, subnet);
                subnet.setMenderId(userId);
                subnet.setRegionId(region);
                subnetRepository.update(subnet);
                subnetMap.remove(model.getSubnetUuid());
                continue;
            }
            BeanUtils.copyProperties(model, subnet);
            subnet.setMenderId(userId);
            subnet.setGmtModify(new Date());
            subnet.setCreatorId(userId);
            subnet.setVendorId(vendorId);
            subnet.setRegionId(region);
            subnetRepository.save(subnet);
            subnetMap.remove(model.getSubnetUuid());
        }
        for (Entry<String, Subnet> entry : subnetMap.entrySet()) {
            subnetRepository.remove(entry.getValue().getId(), userId);
        }
    }

    private void syncRegions(List<RegionModel> regionModels, Long vendorId, Long userId, String regionId)
            throws Exception {
        if (ListTool.isEmpty(regionModels)) {
            regionRepository.deleteByVid(vendorId, regionId);
            zoneRepository.deleteByRegionId(regionId, vendorId);
            return;
        }
        for (RegionModel model : regionModels) {
            // 同步区
            syncZone(model.getZones(), model.getCode(), vendorId);
        }
    }

    private void syncZone(List<ZoneModel> models, String regionId, Long vendorId) throws Exception {
        zoneRepository.deleteByRegionId(regionId, vendorId);
        if (null != models && models.size() > 0) {
            Zone zone = null;
            List<Zone> zoneList = Lists.newArrayList();
            for (ZoneModel model : models) {
                zone = new Zone();
                BeanUtils.copyProperties(model, zone);
                zone.setVendorId(vendorId);
                zone.setRegionId(regionId);
                zoneList.add(zone);
            }
            if (zoneList.size() > 0) {
                zoneRepository.batchSave(zoneList);
            }
        }
    }

	@Override
	protected void register() {
		// TODO Auto-generated method stub
		 
	}

	@Override
	protected void beforeTransport() {
		// TODO Auto-generated method stub
		 
	}

	@Override
	protected void afterTransport() {
		// TODO Auto-generated method stub
		 
	}

}
