package com.bocloud.ims.service.transporter;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ConcurrentLinkedDeque;

import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.bocloud.cmp.driver.common.AuthDriver;
import com.bocloud.cmp.driver.common.LocationDriver;
import com.bocloud.cmp.driver.monitor.AlarmDriver;
import com.bocloud.cmp.entity.enums.ModuleCode;
import com.bocloud.common.enums.BoCloudService;
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.CloudVendor;
import com.bocloud.ims.entity.resource.Region;
import com.bocloud.ims.interfaces.resource.RegionService;
import com.bocloud.ims.interfaces.resource.ResourcePoolService;
import com.bocloud.ims.repository.database.RdsDbRepository;
import com.bocloud.ims.repository.database.RdsPublicCLoudFlavorRepository;
import com.bocloud.ims.repository.database.RdsPublicCloudInstanceParameterGroupRepository;
import com.bocloud.ims.repository.database.RdsPublicCloudInstanceRepository;
import com.bocloud.ims.repository.database.RdsUserRepository;
import com.bocloud.ims.repository.resource.AccessControlRepository;
import com.bocloud.ims.repository.resource.AliCostRepository;
import com.bocloud.ims.repository.resource.BackupRepository;
import com.bocloud.ims.repository.resource.BackupVaultsRepository;
import com.bocloud.ims.repository.resource.BucketObjectRepository;
import com.bocloud.ims.repository.resource.BucketRepository;
import com.bocloud.ims.repository.resource.CidrBlockRepository;
import com.bocloud.ims.repository.resource.CloudServerRepository;
import com.bocloud.ims.repository.resource.CloudVendorRepository;
import com.bocloud.ims.repository.resource.ElasticIpRepository;
import com.bocloud.ims.repository.resource.FirewallPolicyRepository;
import com.bocloud.ims.repository.resource.FirewallRepository;
import com.bocloud.ims.repository.resource.FirewallRuleRepository;
import com.bocloud.ims.repository.resource.FlavorRepository;
import com.bocloud.ims.repository.resource.FloatingIpRepository;
import com.bocloud.ims.repository.resource.ImageRepository;
import com.bocloud.ims.repository.resource.InternetGatewayRepository;
import com.bocloud.ims.repository.resource.KeypairRepository;
import com.bocloud.ims.repository.resource.LbListenerRepository;
import com.bocloud.ims.repository.resource.LbMemberRepository;
import com.bocloud.ims.repository.resource.LbPoolRepository;
import com.bocloud.ims.repository.resource.LoadBalancerRepository;
import com.bocloud.ims.repository.resource.NatGatewayDnatRuleRepository;
import com.bocloud.ims.repository.resource.NatGatewayRepository;
import com.bocloud.ims.repository.resource.NatGatewaySnatRuleRepository;
import com.bocloud.ims.repository.resource.NetworkCardRepository;
import com.bocloud.ims.repository.resource.NetworkHostRepository;
import com.bocloud.ims.repository.resource.NetworkInterfaceRepository;
import com.bocloud.ims.repository.resource.NetworkRepository;
import com.bocloud.ims.repository.resource.OSTenantRepository;
import com.bocloud.ims.repository.resource.PoolGroupRepository;
import com.bocloud.ims.repository.resource.PoolGroupZoneRepository;
import com.bocloud.ims.repository.resource.PortGroupRepository;
import com.bocloud.ims.repository.resource.PortRepository;
import com.bocloud.ims.repository.resource.RegionRepository;
import com.bocloud.ims.repository.resource.ResourceAlarmRepository;
import com.bocloud.ims.repository.resource.ResourceGroupRepository;
import com.bocloud.ims.repository.resource.ResourcePoolRepository;
import com.bocloud.ims.repository.resource.ResourceRepository;
import com.bocloud.ims.repository.resource.RouteRepository;
import com.bocloud.ims.repository.resource.RouteTableRepository;
import com.bocloud.ims.repository.resource.RouterRepository;
import com.bocloud.ims.repository.resource.RouterSubnetRepository;
import com.bocloud.ims.repository.resource.SecurityGroupRepository;
import com.bocloud.ims.repository.resource.SecurityGroupRuleRepository;
import com.bocloud.ims.repository.resource.ServerKeypairRepository;
import com.bocloud.ims.repository.resource.ServerSgroupRepository;
import com.bocloud.ims.repository.resource.SnapshotRepository;
import com.bocloud.ims.repository.resource.SubnetRepository;
import com.bocloud.ims.repository.resource.TagRepository;
import com.bocloud.ims.repository.resource.VolumeRepository;
import com.bocloud.ims.repository.resource.VolumeTypeRepository;
import com.bocloud.ims.repository.resource.VpcRepository;
import com.bocloud.ims.repository.resource.ZoneRepository;
import com.bocloud.ims.service.model.cmdb.CmdbInfo;
import com.bocloud.ims.service.model.cmdb.CmdbModel;
import com.bocloud.ims.service.model.cmdb.CmdbRelation;
import com.bocloud.ims.service.utils.CmdbInfoConvertor;
import com.bocloud.ims.service.utils.ListUtils;
import com.bocloud.ims.service.utils.ProviderRegister;
import com.bocloud.ims.service.utils.ResourceEventPublisher;
import com.bocloud.ims.service.utils.ServerOperationHelper;
import com.bocloud.service.lock.LockFactory;

import lombok.extern.slf4j.Slf4j;

/**抽象平台同步类
 * @author dmw
 */
@Slf4j
public abstract class AbstractTransporter implements ResourceTransporter {
	
	protected final ConcurrentLinkedDeque<ResourceTransporter> transporters = new ConcurrentLinkedDeque<>();

    /**
     * 注册同步实现类
     */
	protected abstract void register();
    
    /**
     * 同步前操作
     */
	protected abstract void beforeTransport();

    /**
     * 同步后操作
     */
	protected abstract void afterTransport();
    
    /**
     * 公有云同步处理
     */
	protected abstract BocloudResult process(CloudVendor vendor, Object data, Region region, Long operator, List<CmdbInfo> infos);
    
    /**
     * 资源同步
     *
     * @param vendor   平台认证信息
     * @param operator 同步操作者ID
     * @return 同步结果
     */
    @Override
    public Result transport(CloudVendor vendor, Long operator) {
        log.info("start to transport vendor {}",vendor.getName());
        beforeTransport();
        transporters.forEach(transporter ->transporter.transport(vendor,operator));
        afterTransport();
        return ResourceTransporter.super.transport(vendor, operator);
    }
    
    /**
     * 公有云同步区域
     * @param context
     * @param vendor
     * @return
     */
    protected BocloudResult syncCloudResource(CloudVendor vendor, Long userId) {
        BocloudResult result = new BocloudResult<>(true, "云平台同步成功！");
        try {
            // 平台配置信息
            JSONObject authentication = JSONObject.parseObject(vendor.getAuthentication());
            String regions = authentication.getString("regions");
            List<String> currentRegions = JSONObject.parseArray(regions, String.class);
            if (ListTool.isEmpty(currentRegions)) {
                throw new RuntimeException("区域信息异常！");
            }
            // cmdb
            CmdbModel model = new CmdbModel();
            model.setUuid(IDFactory.instance().uuid());
            model.setServiceName(BoCloudService.IMS.name());
            model.setManagerId(userId);
            List<CmdbInfo> infos = new ArrayList<>();
            // 汉化区域
            regionService.syncRegion(vendor, userId, currentRegions);
            // CMDB数据需要
            List<String> regionsName = new ArrayList<>();
            List<String> codes = JSON.parseArray(regions, String.class);
            List<Region> vendorRegions = regionRepository.listByRegions(vendor.getId(), codes);
            for (Region region : vendorRegions) {
                regionsName.add(region.getName());
            }
            vendor.setRegionsName(String.valueOf(regionsName));

            infos.add(CmdbInfoConvertor.getInfo(vendor, null, null));
            // cmdb 顺序放置资源
            List<Region> newRegionList = regionRepository.list(vendor.getId());
            for (Region newReg : newRegionList) {
                List<CmdbRelation> relations = new ArrayList<>();
                relations.add(new CmdbRelation(ModuleCode.VENDOR.name(), 1L, ListUtils.getList(vendor.getGuid())));
                newReg.setName(newReg.getName() + " | " + vendor.getName() + "平台");
                infos.add(CmdbInfoConvertor.getInfo(newReg, null, relations));
                result = locationDriver.sync(vendor.getUuid(), newReg.getCode());
                if (result.isFailed()) {
                    break;
                }
                result = this.process(vendor, result.getData(), newReg, userId, infos);
                if (result.isFailed()) {
                    break;
                }
            }
            // 资源同步成功后 创建资源池 同步CMDB
            if (result.isSuccess()) {
                // 创建资源池
            	resourcePoolService.createVendorPoolGroup(vendor, userId);
//            	model.setData(infos);
//                // 发送消息到cmdb模块，进行数据同步
//                CloudProvider type = CloudProvider.valueOf(vendor.getType());
//                switch (type) {
//                    case TENCENT:
//                        messageDispatcher.cacheMessage(JSONObject.toJSONString(model));
//                        break;
//                    default:
//                        break;
//                }
            }
        } catch (Exception e) {
            log.error("sync failure:", e);
            result = new BocloudResult<>(false, e.getMessage());
        }
        return result;
    }
    
    /**
     * 刪除云平台资源
     *
     * @param vendor   平台认证信息
     * @param operator 同步操作者ID
     * @return 同步结果
     */
    @Override
    public Result removeResource(CloudVendor vendor, Long operator) {
        return ResourceTransporter.super.removeResource(vendor, operator);
    }
    
    @Autowired
    protected CloudServerRepository cloudServerRepository;
    @Autowired
    protected SnapshotRepository snapshotRepository;
    @Autowired
    protected NetworkRepository networkRepository;
    @Autowired
    protected LocationDriver locationDriver;
    @Autowired
    protected AuthDriver authDriver;
    @Autowired
    protected AlarmDriver alarmDriver;
    @Autowired
    protected ImageRepository imageRepository;
    @Autowired
    protected CloudVendorRepository cloudVendorRepository;
    @Autowired
    protected ResourceAlarmRepository alarmRepository;
    @Autowired
    protected NetworkCardRepository networkCardRepository;
    @Autowired
    protected VolumeRepository volumeRepository;
    @Autowired
    protected PortGroupRepository portGroupRepository;
    @Autowired
    protected NetworkHostRepository networkHostRepository;
    @Autowired
    protected ResourceEventPublisher resourceEventPublisher;
    @Autowired
    protected ResourceRepository resourceRepository;
    @Autowired
    protected ResourcePoolRepository resourcePoolRepository;
    @Autowired
    protected RouteTableRepository routeTableRepository;
    @Autowired
    protected LockFactory lockFactory;
    @Autowired
    protected AmqpTemplate amqpTemplate;
    @Autowired
    protected SecurityGroupRepository securityGroupRepository;
    @Autowired
    protected SecurityGroupRuleRepository securityGroupRuleRepository;
    @Autowired
    protected ServerSgroupRepository serverSgroupRepository;
    @Autowired
    protected ProviderRegister providerRegister;
    @Autowired
    protected RegionRepository regionRepository;
    @Autowired
    protected FlavorRepository flavorRepository;
    @Autowired
    protected FloatingIpRepository floatingIpRepository;
    @Autowired
    protected KeypairRepository keypairRepository;
    @Autowired
    protected SubnetRepository subnetRepository;
    @Autowired
    protected RouterRepository routerRepository;
    @Autowired
    protected PortRepository portRepository;
    @Autowired
    protected RouteRepository routeRepository;
    @Autowired
    protected FirewallPolicyRepository firewallPolicyRepository;
    @Autowired
    protected FirewallRuleRepository firewallRuleRepository;
    @Autowired
    protected LoadBalancerRepository loadBalancerRepository;
    @Autowired
    protected LbListenerRepository lbListenerRepository;
    @Autowired
    protected LbMemberRepository lbMemberRepository;
    @Autowired
    protected LbPoolRepository lbPoolRepository;
    @Autowired
    protected RouterSubnetRepository routerSubnetRepository;
    @Autowired
    protected ServerOperationHelper serverOperationHelper;
    @Autowired
    protected FirewallRepository firewallRepository;
    @Autowired
    protected VpcRepository vpcRepository;
    @Autowired
    protected ThreadPoolTaskExecutor taskExecutor;
    @Autowired
    protected PoolGroupRepository poolGroupRepository;
    @Autowired
    protected PoolGroupZoneRepository poolGroupZoneRepository;
    @Autowired
    protected ServerKeypairRepository serverKeypairRepository;
    @Autowired
    protected ElasticIpRepository elasticIpRepository;
    @Autowired
    protected NatGatewayRepository natGatewayRepository;
    @Autowired
    protected NatGatewaySnatRuleRepository natGatewaySnatRuleRepository;
    @Autowired
    protected NatGatewayDnatRuleRepository natGatewayDnatRuleRepository;
    @Autowired
    protected CidrBlockRepository cidrBlockRepository;
    @Autowired
    protected InternetGatewayRepository internetGatewayRepository;
    @Autowired
    protected NetworkInterfaceRepository networkInterfaceRepository;
    @Autowired
    protected RegionService regionService;
    @Autowired
    protected ResourcePoolService resourcePoolService;
    @Autowired
    protected ZoneRepository zoneRepository;
    @Autowired
    protected AliCostRepository aliCostRepository;
    @Autowired
    protected RdsPublicCloudInstanceRepository rdsPublicCloudInstanceRepository;
    @Autowired
    protected RdsPublicCLoudFlavorRepository rdsPublicCLoudFlavorRepository;
    @Autowired
    protected RdsPublicCloudInstanceParameterGroupRepository rdsPublicCloudInstanceParameterGroupRepository;
    @Autowired
    protected RdsUserRepository rdsUserRepository;
    @Autowired
    protected RdsDbRepository rdsDbRepository;
    @Autowired
    protected BucketRepository bucketRepository;
    @Autowired
    protected BucketObjectRepository bucketObjectRepository;
    @Autowired
    protected AccessControlRepository accessControlRepository;
    @Autowired
    protected ResourceGroupRepository resourceGroupRepository;
    @Autowired
    protected TagRepository tagRepository;
    @Autowired
    protected VolumeTypeRepository volumeTypeRepository;
    @Autowired
    protected OSTenantRepository osTenantRepository;
    @Autowired
    protected BackupVaultsRepository backupVaultsRepository;
    @Autowired
    protected BackupRepository backupRepository;
    
}
