package cn.iocoder.yudao.module.ocr.framework.ocr.core.client;

import cn.hutool.core.lang.Assert;
import cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil;
import cn.iocoder.yudao.module.ocr.enums.ErrorCodeConstants;
import cn.iocoder.yudao.module.ocr.framework.ocr.core.client.impl.BaiduOcrClient;
import cn.iocoder.yudao.module.ocr.framework.ocr.core.client.impl.BaiduOcrClientConfig;
import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

/**
 * OCR 客户端工厂实现类
 */
@Slf4j
public class OcrClientFactoryImpl implements OcrClientFactory {

    /**
     * OCR 客户端 Map
     * key：厂商编码
     */
    private final ConcurrentMap<String, OcrClient> clients = new ConcurrentHashMap<>();

    /**
     * 默认厂商
     */
    private String defaultProvider;

    public OcrClientFactoryImpl(String defaultProvider) {
        this.defaultProvider = defaultProvider;
    }

    @Override
    public OcrClient getDefaultClient() {
        return getClient(defaultProvider);
    }

    @Override
    public OcrClient getClient(String provider) {
        OcrClient client = clients.get(provider);
        if (client == null) {
            log.error("[getClient][厂商({}) 找不到客户端]", provider);
            throw ServiceExceptionUtil.exception(ErrorCodeConstants.OCR_PROVIDER_NOT_SUPPORTED);
        }
        return client;
    }

    /**
     * 创建或更新客户端
     */
    public <Config extends OcrClientConfig> void createOrUpdateClient(String provider, Config config) {
        OcrClient client = clients.get(provider);
        if (client == null) {
            client = createClient(provider, config);
            if (client instanceof AbstractOcrClient) {
                ((AbstractOcrClient<?>) client).init();
            }
            clients.put(provider, client);
            log.info("[createOrUpdateClient][创建 OCR 客户端成功，厂商：{}]", provider);
        }
    }

    /**
     * 创建客户端
     */
    @SuppressWarnings("unchecked")
    private <Config extends OcrClientConfig> OcrClient createClient(String provider, Config config) {
        switch (provider) {
            case "baidu":
                Assert.isInstanceOf(BaiduOcrClientConfig.class, config, "百度 OCR 配置类型错误");
                return new BaiduOcrClient((BaiduOcrClientConfig) config);
            // 预留其他厂商
            default:
                throw ServiceExceptionUtil.exception(ErrorCodeConstants.OCR_PROVIDER_NOT_SUPPORTED);
        }
    }

}
