#include <iostream>
#include <cstring>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>

// Clase que representa el medidor y maneja la lectura de valores instantáneos
class Medidor {
private:
    int sock;
    struct sockaddr_in server;

public:
    Medidor(const std::string& ip, int puerto) {
        // Crear el socket
        sock = socket(AF_INET, SOCK_STREAM, 0);
        if (sock == -1) {
            std::cerr << "No se pudo crear el socket" << std::endl;
            exit(EXIT_FAILURE);
        }

        server.sin_addr.s_addr = inet_addr(ip.c_str());
        server.sin_family = AF_INET;
        server.sin_port = htons(puerto);

        // Conectar al medidor
        if (connect(sock, (struct sockaddr*)&server, sizeof(server)) < 0) {
            std::cerr << "Error de conexión" << std::endl;
            exit(EXIT_FAILURE);
        }

        std::cout << "Conectado al medidor en " << ip << ":" << puerto << std::endl;
    }

    ~Medidor() {
        close(sock);
    }

    // Método que envía comandos al medidor y obtiene los valores instantáneos
    void leerInstantaneos() {
        unsigned char buffer[1024];
        int bytesLeidos;

        // Ejemplo de comando para solicitar valores instantáneos
        const char* comando = "\x68\x04\x07\x00\x00\x00";  // Comando IEC 60870 (placeholder)
        send(sock, comando, strlen(comando), 0);

        // Leer la respuesta del medidor
        bytesLeidos = recv(sock, buffer, sizeof(buffer), 0);

        if (bytesLeidos > 0) {
            // Interpretación básica del buffer recibido
            // Esto dependerá del formato específico del medidor y del protocolo IEC 60870

            std::cout << "Valores instantáneos recibidos:" << std::endl;
            for (int i = 0; i < bytesLeidos; i++) {
                printf("Byte %d: 0x%02X\n", i, buffer[i]);
            }
        } else {
            std::cerr << "Error al leer los datos del medidor" << std::endl;
        }
    }
};

// Programa principal
int main(int argc, char* argv[]) {
    if (argc != 3) {
        std::cerr << "Uso: " << argv[0] << " <IP> <Puerto>" << std::endl;
        return 1;
    }

    std::string ip = argv[1];
    int puerto = std::stoi(argv[2]);

    Medidor medidor(ip, puerto);
    medidor.leerInstantaneos();

    return 0;
}