package com.yingxin.prms.service.asyncTask;

import com.yingxin.prms.domain.Server_Host_Info;
import org.kairosdb.client.HttpClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Base64;
import java.util.concurrent.ConcurrentHashMap;

@Component
public class UdpTask extends BasicTask{

    private static Logger logger = LoggerFactory.getLogger(UdpTask.class);

    private final HttpClient httpClient;

    @Autowired
    public UdpTask(HttpClient httpClient) {
        this.httpClient = httpClient;
    }

    @Async("asyncTaskPool")
    public void doTask(Server_Host_Info hostInfo, ConcurrentHashMap<String, String> alarmHost) {
        String ip = hostInfo.getService_path();
        short port = hostInfo.getHost_port();
        byte[] auAppSPData = Base64.getDecoder().decode(hostInfo.getRequest_body());
        byte[] applicationReturn;
        InetAddress ia = null;
        try {
            ia = InetAddress.getByName(ip);
        } catch (UnknownHostException e) {
            e.printStackTrace();
        }
        DatagramPacket sendPacket = new DatagramPacket(auAppSPData, auAppSPData.length, ia, port);
        DatagramPacket receivePacket = new DatagramPacket(new byte[1], 1);
        long dur = 0;
        long start = System.currentTimeMillis();
        try (DatagramSocket udpClient = new DatagramSocket()) {
            udpClient.send(sendPacket);
            udpClient.setSoTimeout(300);
            udpClient.receive(receivePacket);
            applicationReturn = receivePacket.getData();
            dur = System.currentTimeMillis() - start;
        } catch (IOException e) {
            logger.debug("error: udpTask to {}", hostInfo.getService_path());
            insertToKairos(httpClient,  hostInfo.getService_path(), dur, false);
            return;
        }
        boolean isAlive = applicationReturn.length > 0;
        insertToKairos(httpClient, ip, dur, isAlive);
        if (isAlive) {
            alarmHost.remove(hostInfo.getService_path());
        }
    }
}
