package com.ruoyi.tcp;

import cn.hutool.core.io.BufferUtil;
import cn.hutool.core.io.IORuntimeException;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.socket.nio.NioServer;
import com.alibaba.fastjson.JSONObject;
import com.ruoyi.framework.web.service.ConfigService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.io.IOException;
import java.lang.reflect.Field;
import java.nio.ByteBuffer;
import java.nio.channels.SocketChannel;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

@Component
public class TcpServer  extends Thread implements CommandLineRunner {

    @Resource
    private ConfigService configService;

    private static final Logger log = LoggerFactory.getLogger(TcpServer.class);
    private static final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    @Override
    public void run(String... args){
        Integer port = Integer.parseInt(configService.getKey("port"));
        NioServer server = new NioServer(port);
        server.setChannelHandler((sc)->{
            ByteBuffer readBuffer = ByteBuffer.allocate(1024);
            try{
                int readBytes = sc.read(readBuffer);
                if (readBytes > 0) {
                    readBuffer.flip();
                    byte[] bytes = new byte[readBuffer.remaining()];
                    readBuffer.get(bytes);
                    String body = StrUtil.utf8Str(bytes);
                    readAndWrite(sc, body);
                } else if (readBytes < 0) {
                    IoUtil.close(sc);
                }
            } catch (IOException e){
                throw new IORuntimeException(e);
            }
        });
        server.listen();
    }

    public void readAndWrite(SocketChannel channel, String response) throws IOException {
        JSONObject object;
        try {
            object = JSONObject.parseObject(response);
            //先推送
            String result = HttpRequest.post(configService.getKey("centerMonitorURL")+"device/saveWaterMonitoringData")
                    .header("Content-Type", "application/json")
                    .body(object.toJSONString())
                    .execute().body();
            System.out.println(result);
        } catch (Exception e) {
            e.printStackTrace();
            return;
        }
        //返回客户端数据
        String st = object.get("ST").toString();
        Integer serial = Integer.parseInt(object.get("SERIAL").toString());
        JSONObject res = new JSONObject();
        res.put("ST",st);
        res.put("SERIAL",serial);
        res.put("MARK",1);
        res.put("TM", sdf.format(new Date()));
        //将缓冲数据写入渠道，返回给客户端
        channel.write(BufferUtil.createUtf8(res.toJSONString()));
    }


    /**
     * 对象转Map
     * @param object
     * @return
     * @throws IllegalAccessException
     */
    public static Map beanToMap(Object object){
        Map<String, Object> map = new HashMap<>();
        Field[] fields = object.getClass().getDeclaredFields();
        for (Field field : fields) {
            field.setAccessible(true);
            try {
                map.put(field.getName(), field.get(object));
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
        }
        return map;
    }


}


