package org.nl.acs.utils;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import lombok.extern.slf4j.Slf4j;
import org.jinterop.dcom.common.JIException;
import org.jinterop.dcom.core.JIVariant;
import org.nl.acs.device.device_driver.standard_inspect.ItemDto;
import org.nl.acs.device.device_driver.standard_inspect.ItemProtocol;
import org.nl.acs.opc.OpcUtl;
import org.nl.acs.opc.domain.Opc;
import org.nl.acs.opc.service.mapper.OpcMapper;
import org.nl.common.exception.BadRequestException;
import org.nl.config.SpringContextHolder;
import org.openscada.opc.dcom.list.ClassDetails;
import org.openscada.opc.lib.common.AlreadyConnectedException;
import org.openscada.opc.lib.common.ConnectionInformation;
import org.openscada.opc.lib.da.*;
import org.openscada.opc.lib.list.Categories;
import org.openscada.opc.lib.list.Category;
import org.openscada.opc.lib.list.ServerList;

import java.net.UnknownHostException;
import java.util.*;
import java.util.concurrent.Executors;

@Slf4j
public class ReadUtil {

    static OpcMapper opcMapper = SpringContextHolder.getBean("opcMapper");

    public static Server getServer(String opc_id) {
        //OPC表【acs_opc】
        Opc opc = new LambdaQueryChainWrapper<>(opcMapper)
                .eq(Opc::getOpc_id,opc_id)
                .one();
        //RD1.RD1.1028
        // 连接信息
        ConnectionInformation ci = new ConnectionInformation();
        ci.setHost(opc.getOpc_host());
        ci.setDomain(opc.getDomain());
        ci.setUser(opc.getUser());
        ci.setPassword(opc.getPassword());
        ci.setClsid(opc.getCls_id());
        final Server server = new Server(ci, Executors.newSingleThreadScheduledExecutor());
        try {
            server.connect();
        } catch (UnknownHostException e) {
            e.printStackTrace();
        } catch (JIException e) {
            e.printStackTrace();
        } catch (AlreadyConnectedException e) {
            e.printStackTrace();
        }
        return server;
    }

    public static void write(Map<String, Object> strings, Server server) {
        try {
            //Group group = this.opcServerService.getServer(opcServiceCode);
            Group group = server.addGroup();
            Iterator it = strings.keySet().iterator();
            while (it.hasNext()) {
                String key = (String) it.next();
                Item byteItem = group.addItem(key);
                Object o = strings.get(key);
                if (o == null || o.equals("")) {
                    break;
                }
                WriteRequest write1 = new WriteRequest(byteItem, new JIVariant(o.toString()));
                List<WriteRequest> list = new ArrayList();
                list.add(write1);
                OpcUtl.writeValue(group, (WriteRequest[]) list.toArray(new WriteRequest[0]));
            }
            server.disconnect();
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    public static JSONArray getReadableItemDtos() {
        List<ItemDto> list = ItemProtocol.getReadableItemDtos();
        JSONArray array = JSONArray.parseArray(JSON.toJSONString(list));

        return array;

    }

    public static JSONArray getWriteableItemDtos() {
        List<ItemDto> list = ItemProtocol.getWriteableItemDtos();
        JSONArray array = JSONArray.parseArray(JSON.toJSONString(list));
        return array;

    }

    public static Map<String, Object> read(List<String> itemString, Server server) {
        HashMap map = new HashMap();
        try {
            Group group = server.addGroup();
            Map<String, Item> items = new LinkedHashMap();
            Iterator is = itemString.iterator();

            while (is.hasNext()) {
                String string = (String) is.next();
                try {
                    items.put(string, group.addItem(string));
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }

            Map<Item, ItemState> itemStatus = group.read(true, (Item[]) items.values().toArray(new Item[0]));
            Set<Item> keySet = itemStatus.keySet();
            Iterator it = keySet.iterator();

            while (it.hasNext()) {
                Item key = (Item) it.next();
                Object value = OpcUtl.getValue(key, (ItemState) itemStatus.get(key));
                map.put(key.getId(), value);
            }
            server.disconnect();

        } catch (Exception e) {
            e.printStackTrace();
        }

        return map;
    }

    public static List<Map<String, String>> showAllOpcServer(String host, String user, String password, String domain) throws BadRequestException {
        try {
            List<Map<String, String>> listResult = new ArrayList();
            ServerList serverList = new ServerList(host, user, password, domain);
            Collection<ClassDetails> classDetails = serverList.listServersWithDetails(new Category[]{Categories.OPCDAServer10, Categories.OPCDAServer20, Categories.OPCDAServer30}, new Category[0]);
            Iterator var7 = classDetails.iterator();

            while (var7.hasNext()) {
                ClassDetails details = (ClassDetails) var7.next();
                Map<String, String> result = new LinkedHashMap();
                result.put("classId", details.getClsId());
                result.put("progId", details.getProgId());
                result.put("description", details.getDescription());
                listResult.add(result);
            }

            return listResult;
        } catch (UnknownHostException | JIException | IllegalArgumentException e) {
            log.error("连接异常{}",e,e.getMessage());
            throw new BadRequestException("用户名或密码错误");
        }
    }

}
