package com.bocloud.cmp.acd.factory;

import com.alibaba.fastjson.JSON;
import com.bocloud.acd.common.utils.Sha256Util;
import com.bocloud.acd.provider.ProviderContext;
import com.bocloud.acd.provider.factory.ProviderSessionFactory;
import com.bocloud.cmp.model.Butler;
import com.bocloud.cmp.provider.ButlerProviderSession;
import com.bocloud.cmp.provider.ButlerRepository;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;

import java.security.NoSuchAlgorithmException;
import java.util.HashMap;
import java.util.Map;

@Service
public class ButlerProviderSessionFactory extends ProviderSessionFactory<ButlerProviderSession> implements InitializingBean {

    ButlerRepository butlerRepository = ButlerRepository.getInstance();

    @Autowired
    ConfigurableListableBeanFactory beanFactory;

    Map<String, ButlerProviderSessionSupplier<ButlerProviderSession>> providerSessionSupplerMap = new HashMap<>();


    @Override
    protected String computeAuthenticationHash(ProviderContext providerContext) {
        String uuid = providerContext.getCloudVendor().getUuid();
        Butler butler = butlerRepository.get(uuid);
        String jsonString = JSON.toJSONString(butler);
        String hash = null;
        try {
            hash = Sha256Util.generateHash(jsonString);
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException(e);
        }
        Assert.notNull(hash, "hash must not be null");
        return hash;
    }

    @Override
    protected ButlerProviderSession onBuildProviderSession(ProviderContext providerContext) {
        String uuid = providerContext.getCloudVendor().getUuid();
        Butler butler = butlerRepository.get(uuid);
        String type = providerContext.getCloudVendor().getType();
        ButlerProviderSessionSupplier<ButlerProviderSession> suppler = providerSessionSupplerMap.get(type);
        Assert.notNull(suppler, "找不到供应器，请检查供应器的配置是否正确，Session泛型是否符合等");
        suppler.setButler(butler);
        return suppler.onBuildProviderSession(providerContext);
    }


    @Override
    public void afterPropertiesSet() throws Exception {
        beanFactory.getBeansOfType(ButlerProviderSessionSupplier.class).forEach((k, v) -> {
            String vendorType = v.getVendorType();
            providerSessionSupplerMap.put(vendorType, v);
        });
    }
}
