package com.xydl.cac.iec;

import com.beanit.iec61850bean.*;
import com.xydl.cac.entity.IcdTransform;
import com.xydl.cac.model.StaticVariable;
import com.xydl.cac.service.IcdTransformService;
import com.xydl.cac.service.impl.IcdTransformServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;
import org.springframework.util.CollectionUtils;

import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;

@Slf4j
public class IecServer implements ServerEventListener {
    ServerSap serverSap = null;
    ServerModel serversServerModel = null;
    public boolean started = false;
    public String filename = null;
    public Integer port = null;
    IcdTransformService _transformService;

    public IecServer(IcdTransformService transformService) {
        _transformService = transformService;
    }

    public void start(String xml, int port) throws Exception {
        if (!started) {
            InputStream in = IOUtils.toInputStream(xml, StandardCharsets.UTF_8);
            serverSap = new ServerSap(port, 0, null, SclParser.parse(in).get(0), null);

            serverSap.setPort(port);
            serverSap.startListening(this);
            serversServerModel = serverSap.getModelCopy();
            started = true;
            this.port = port;
            log.info("已启动IEC61850服务端在" + port + "端口");
        }
    }

    public void stop() {
        if (serverSap != null) {
            serverSap.stop();
            log.info("已停止IEC61850服务端于" + port + "端口");
        }
        started = false;
    }

    public void updateBda(BasicDataAttribute bda) {
        String ref = bda.getReference().toString();
        List<IcdTransform> list = _transformService.listTransform();
        String rptTo = "";
        if (!CollectionUtils.isEmpty(list)) {
            for (IcdTransform item : list) {
                if (ref.startsWith(item.getRptFrom())) {
                    ref = ref.replace(item.getRptFrom(), item.getRptTo());
                    rptTo = item.getRptTo();
                    StaticVariable.rptFromActiveMap.put(item.getRptFrom(), "1");
                    break;
                }
            }
        }
        BasicDataAttribute node = (BasicDataAttribute) serversServerModel.findModelNode(ref, bda.getFc());
        if (node != null) {
            node.setValueFrom(bda);
            List<BasicDataAttribute> bdas = new ArrayList<>();
            bdas.add(node);
            StaticVariable.rptToActiveMap.put(rptTo, "1");
            serverSap.setValues(bdas);
        } else {
            StaticVariable.rptToActiveMap.remove(rptTo);
        }
    }

    @Override
    public List<ServiceError> write(List<BasicDataAttribute> bdas) {
        return null;
    }

    @Override
    public void serverStoppedListening(ServerSap serverSAP) {

    }
}
