import socket
import json
import threading
import argparse

class DualModeSocketListener:
    def __init__(self, host, port, mode):
        self.host = host
        self.port = port
        self.mode = mode
        self.sock = None

    def start(self):
        if self.mode == 'server':
            self.start_server()
        elif self.mode == 'client':
            self.start_client()

    def start_server(self):
        self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.sock.bind((self.host, self.port))
        self.sock.listen(1)
        print("Servidor escuchando en {0}:{1}".format(self.host, self.port))
        while True:
            conn, addr = self.sock.accept()
            print("Conexión establecida desde {0}".format(addr))
            threading.Thread(target=self.handle_client, args=(conn, addr)).start()

    def start_client(self):
        self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        try:
            self.sock.connect((self.host, self.port))
            print("Cliente conectado a {0}:{1}".format(self.host, self.port))
            self.handle_client(self.sock, (self.host, self.port))
        except Exception as e:
            print("No se pudo conectar a {0}:{1}. Error: {2}".format(self.host, self.port, e))

    def handle_client(self, conn, addr):
        try:
            while True:
                data = conn.recv(4096)
                if not data:
                    break
                try:
                    json_data = json.loads(data.decode('utf-8'))
                    print("Mensaje recibido de {0}: {1}".format(addr, json_data))
                except json.JSONDecodeError:
                    print("Mensaje no válido recibido de {0}: {1}".format(addr, data.decode('utf-8')))
        except Exception as e:
            print("Error al manejar la conexión con {0}. Error: {1}".format(addr, e))
        finally:
            conn.close()
            print("Conexión cerrada con {0}".format(addr))

def main():
    parser = argparse.ArgumentParser(description="Dual Mode Socket Listener")
    parser.add_argument('--mode', choices=['client', 'server'], required=True, help="Modo de operación: cliente o servidor")
    parser.add_argument('--connections', nargs='+', required=True, help="Lista de conexiones en formato 'host:puerto'")
    args = parser.parse_args()

    listeners = []
    for conn in args.connections:
        host, port = conn.split(':')
        listeners.append(DualModeSocketListener(host, int(port), args.mode))

    threads = []
    for listener in listeners:
        thread = threading.Thread(target=listener.start)
        thread.start()
        threads.append(thread)

    for thread in threads:
        thread.join()

if __name__ == "__main__":
    main()