package com.sunyard.chsm.sdf.adapter;

import com.googlecode.jsonrpc4j.JsonRpcHttpClient;
import com.googlecode.jsonrpc4j.ProxyUtil;
import com.sun.jna.Platform;
import com.sunyard.chsm.enums.ManufacturerModelEnum;
import com.sunyard.chsm.utils.JsonUtils;
import lombok.extern.slf4j.Slf4j;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;

import java.lang.reflect.Proxy;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Collections;
import java.util.Objects;

/**
 * @author liulu
 * @since 2024/11/5
 */
@Slf4j
public class SdfApiAdapterFactory {


    public static SdfApiAdapter getBcAdapter() {
        return BcSdfApiAdaptor.INSTANCE;
    }

    public static SdfApiAdapter newInstance(String model, String ip, Integer port) {

        Assert.hasText(model, "设备型号不能为空");
        ManufacturerModelEnum modelEnum = ManufacturerModelEnum.of(model);

        if (Objects.isNull(modelEnum) && Objects.equals(BouncyCastleProvider.PROVIDER_NAME, model)) {
            // bc adaptor
            return BcSdfApiAdaptor.INSTANCE;
        }
        switch (modelEnum) {
            case enc001:
                return Platform.isMac() ? getProxyRcpAdapter(ip, port) : new SunyardJnaSdfAdaptor(ip, port);
            default:
                throw new UnsupportedOperationException("不支持的设备型号: " + model);
        }
    }

    private static final RpcSdfAdapter rpcSdfAdapter;

    static {
        try {
            JsonRpcHttpClient client = new JsonRpcHttpClient(JsonUtils.objectMapper(),
                    new URL("http://172.16.18.46:9989/sdf/adapter"), Collections.emptyMap());
            rpcSdfAdapter = ProxyUtil.createClientProxy(
                    ClassUtils.getDefaultClassLoader(), RpcSdfAdapter.class, client);
        } catch (MalformedURLException e) {
            throw new RuntimeException(e);
        }
    }

    private static SdfApiAdapter getProxyRcpAdapter(String ip, Integer port) {
        return (SdfApiAdapter) Proxy.newProxyInstance(ClassUtils.getDefaultClassLoader(),
                new Class[]{SdfApiAdapter.class},
                (proxy, method, args) -> {
                    if (Objects.equals(method.getName(), "openDevice")) {
                        return rpcSdfAdapter.openDevice(ip, port, 3000, 3000, 0);
                    }
                    return method.invoke(rpcSdfAdapter, args);
                }
        );
    }


}
