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

int main(int argc, char *argv[]) {
    if (argc != 3) {
        std::cerr << "Uso: " << argv[0] << " <dirección IP> <puerto>" << std::endl;
        return 1;
    }

    const char* ip_address = argv[1];
    int port = atoi(argv[2]);

    if (port <= 0 || port > 65535) {
        std::cerr << "Error: El puerto debe estar entre 1 y 65535." << std::endl;
        return 1;
    }

    int sock = 0;
    struct sockaddr_in serv_addr;
    
    // Crear socket
    if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
        std::cerr << "Error de creación de socket" << std::endl;
        return -1;
    }

    serv_addr.sin_family = AF_INET;
    serv_addr.sin_port = htons(port);

    // Convertir dirección IP de texto a binario
    if (inet_pton(AF_INET, ip_address, &serv_addr.sin_addr) <= 0) {
        std::cerr << "Dirección inválida / Dirección no soportada" << std::endl;
        return -1;
    }

    // Conectar al servidor
    if (connect(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) {
        std::cerr << "Conexión fallida" << std::endl;
        return -1;
    }

    std::cout << "Conectado al medidor Circutor en " << ip_address << ":" << port << std::endl;

    Medidor medidor;
    medidor.setSocket(sock);

    // Iniciar comunicación con el medidor
    if (medidor.autenticarMedidor() != COMUNICACION_EXITOSA) {
        std::cerr << "Error en la autenticación con el medidor" << std::endl;
        close(sock);
        return -1;
    }

    // Leer valores instantáneos
    while (true) {
        if (medidor.leerInstantaneos(194) == COMUNICACION_EXITOSA) {
            std::cout << "Valores instantáneos:" << std::endl;
            for (int i = 0; i < REGISTROS_MAXIMOS; i++) {
                std::cout << "Registro " << i << ": " << medidor.getRegistros(i) << std::endl;
            }
        } else {
            std::cerr << "Error al leer valores instantáneos" << std::endl;
        }

        sleep(5); // Esperar 5 segundos antes de la siguiente lectura
    }

    close(sock);
    return 0;
}