import socket
import time
import re

class SimpleUDPClient:
    def __init__(self, host='192.168.0.50', port=5009):
        self.host = host
        self.port = port
        
        # Создаем UDP сокет
        self.sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        self.sock.settimeout(0.1)  # Таймаут 2 секунды
        
        print(f"UDP client initialized for {host}:{port}")
    
    def send_command(self, command="GET_P2"):
        """Отправка команды по UDP"""
        try:
            message = command + '\r\n'
            self.sock.sendto(message.encode('utf-8'), (self.host, self.port))
            print(f"Sent: {command}")
            return True
        except Exception as e:
            print(f"Send error: {e}")
            return False
    
    def receive_data(self):
        """Получение данных по UDP"""
        try:
            data, addr = self.sock.recvfrom(1024)  # Буфер 1024 байта
            decoded_data = data.decode('utf-8', errors='ignore').strip()
            print(f"Received from {addr}: {decoded_data}")
            return decoded_data
        except socket.timeout:
            print("Timeout: no data received")
            return None
        except Exception as e:
            print(f"Receive error: {e}")
            return None
    
    def get_data(self):
        """Отправка команды и получение ответа"""
        if self.send_command("GET_P2"):
            return self.receive_data()
        return None
    
    def close(self):
        """Закрытие сокета"""
        self.sock.close()
        print("UDP socket closed")

# Функция для тестирования соединения
def test_udp_connection(host='192.168.0.50', port=5009):
    """Тестирование UDP соединения"""
    print(f"Testing UDP connection to {host}:{port}...")
    
    try:
        client = SimpleUDPClient(host, port)
        
        # Тестовый запрос
        print("Sending test command...")
        response = client.get_data()
        
        if response:
            print(f"✓ Success! Response: {response}")
            
            # Парсим данные если пришли в нужном формате
            pattern = re.compile(
                r'PRT2TSM(-?\d+)PRL(-?\d+)PRU(-?\d+)PRP(-?\d+)STA(-?\d+)STB(-?\d+)LCA(-?\d+)LCB(-?\d+)WSA(-?\d+)WSB(-?\d+)'
            )
            match = pattern.match(response)
            
            if match:
                print("✓ Data parsed successfully:")
                print(f"  Runtime: {match.group(1)} ms")
                print(f"  Loader: {match.group(2)}, Unloader: {match.group(3)}")
                print(f"  Processor: {match.group(4)}")
                print(f"  STB: {match.group(5)}, {match.group(6)}")
                print(f"  AVG: {match.group(7)}, {match.group(8)}")
                print(f"  Weight: {match.group(9)}, {match.group(10)} g")
            else:
                print("⚠ Response format doesn't match expected pattern")
                
            client.close()
            return True
        else:
            print("✗ No response received")
            client.close()
            return False
            
    except Exception as e:
        print(f"✗ Connection test failed: {e}")
        return False

# Функция для непрерывного опроса
def continuous_polling(host='192.168.0.50', port=5009, interval=1.0):
    """Непрерывный опрос устройства"""
    print(f"Starting continuous polling every {interval} seconds...")
    print("Press Ctrl+C to stop")
    
    client = SimpleUDPClient(host, port)
    message_count = 0
    
    try:
        while True:
            message_count += 1
            print(f"\n--- Message #{message_count} ---")
            
            response = client.get_data()
            
            if response:
                # Простой парсинг для отображения
                if 'PRT2TSM' in response:
                    print("✓ Valid data format received")
                else:
                    print("⚠ Unknown response format")
            
            time.sleep(interval)
            
    except KeyboardInterrupt:
        print("\nStopped by user")
    except Exception as e:
        print(f"Error: {e}")
    finally:
        client.close()

# Функция для массового тестирования
def stress_test(host='192.168.0.50', port=5009, count=10, delay=0.1):
    """Тестирование с множественными запросами"""
    print(f"Stress test: {count} requests with {delay}s delay")
    
    client = SimpleUDPClient(host, port)
    success_count = 0
    
    for i in range(count):
        print(f"\nRequest {i+1}/{count}:")
        response = client.get_data()
        
        if response:
            success_count += 1
            print("✓ Success")
        else:
            print("✗ Failed")
        
        time.sleep(delay)
    
    client.close()
    print(f"\nTest completed: {success_count}/{count} successful")
    return success_count

# Основная программа
if __name__ == "__main__":
    HOST = '192.168.0.50'
    PORT = 5009
    
    print("=" * 50)
    print("UDP Debug Client for Device Communication")
    print("=" * 50)
    
    while True:
        print("\nChoose mode:")
        print("1. Single test")
        print("2. Continuous polling")
        print("3. Stress test")
        print("4. Exit")
        
        choice = input("Enter choice (1-4): ").strip()
        
        if choice == '1':
            test_udp_connection(HOST, PORT)
        
        elif choice == '2':
            try:
                interval = float(input("Polling interval (seconds): ") or "1.0")
                continuous_polling(HOST, PORT, interval)
            except ValueError:
                print("Invalid interval, using 1.0 second")
                continuous_polling(HOST, PORT, 1.0)
        
        elif choice == '3':
            try:
                count = int(input("Number of requests: ") or "10")
                delay = float(input("Delay between requests (seconds): ") or "0.1")
                stress_test(HOST, PORT, count, delay)
            except ValueError:
                print("Invalid input, using default values")
                stress_test(HOST, PORT, 10, 0.1)
        
        elif choice == '4':
            print("Goodbye!")
            break
        
        else:
            print("Invalid choice, please try again")