import org.pcap4j.core.*;

import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.nio.charset.StandardCharsets;
import java.util.List;

public class BcowClient {

    private ClientConfig config;
    private static final int SNAPLEN = 65536;
    private static final int TIMEOUT = 10; // in milliseconds

    public BcowClient(ClientConfig config) {
        this.config = config;
    }

    public void sniffAndSendPackets() {
        System.out.println("Sending inital heartbeat data...");
        System.out.println("Starting packet sniff func...");
        PcapNetworkInterface device = null;
        try {
            List<PcapNetworkInterface> allDevs = Pcaps.findAllDevs();
            System.out.println(allDevs.toString());
            if (allDevs.isEmpty()) {
                System.err.println("No devices found.");
                return;
            }
            device = allDevs.get(4); // Get the first available network interface
        } catch (PcapNativeException e) {
            e.printStackTrace();
        }

        if (device == null) {
            System.err.println("No device found.");
            return;
        }

        PcapHandle handle;
        System.out.println("Opening live capture on device: " + device.getName());
        try {
            handle = device.openLive(SNAPLEN, PcapNetworkInterface.PromiscuousMode.PROMISCUOUS, TIMEOUT);
            System.out.println("Live capture handle opened successfully.");
        } catch (PcapNativeException e) {
            System.err.println("Error opening live capture: " + e.getMessage());
            e.printStackTrace();
            return;
        }

        PacketListener listener = packet -> {
            System.out.println("Received packet: " + packet);
            String packetData = packet.toString();

            String[] lines = packetData.split("\\r?\\n");

            for (String line : lines) {
                //sendPacketData(line);
            }
        };


        try {
            handle.loop(-1, listener);
        } catch (InterruptedException | PcapNativeException | NotOpenException e) {
            e.printStackTrace();
        } finally {
            if (handle != null && handle.isOpen()) {
                handle.close();
            }
        }
    }

    private void sendPacketData(String line) {
        try (Socket socket = new Socket(config.getServerIp(), 9999);
             DataOutputStream dos = new DataOutputStream(socket.getOutputStream())) {

            String dataToSend = String.format("ID:%s|NAME:%s|TIMEZONE:%s|DATA:%s",
                    config.getId(), config.getName(), config.getTimezone(), line);
            dos.write(dataToSend.getBytes(StandardCharsets.UTF_8));
            dos.flush();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


    public static void main(String[] args) {
        ClientConfig config = new ClientConfig("001", "Client1", "127.0.0.1", "auto");
        BcowClient client = new BcowClient(config);
        client.sniffAndSendPackets();
    }
}
