import requests
import json

# Constants from the Wireshark capture
PUBLIC_KEY = """-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCMl89OZsjqE8yZ9TQhUb9h539WTX3U8Y5YCNdp
OhuXvLFYcAT5mvC074VFROmD0xhvw5hrwESOisqpPPU9r78JpLuYUKd+/aidvykqBT8OW5rDLb6d
O9FO6Gc+bV8L8ttHVlBFoX69EqiRhcreGPG6FQz4JqGJF4T1nFi0EvALXwIDAQAB
-----END PUBLIC KEY-----"""

# Vorbereitete verschlüsselte Befehle (aus Wireshark extrahiert)
COMMAND_ON = """ps0Puxc37EK4PhfcevceL3lyyDrjwLT1+443DDXNbcNRsltlgCQ6+oXgsrE2Pl5OhV73ZI/oM5Nj
37cWEaHpXPiHdr1W0cD3aJ5qJ55TfTRkHP9xcMNQJHCn6aWPEHpR7xvvXW9WbJWfShnE2Xdvmw==
"""

COMMAND_OFF = """FlO5i3DRcrUmu2ZwIIv8b68EisGu8VCuqfGOydaR+xCA0n3f2W/EcqVj8MurRBFXYTrZ/uwa1W26
ftCfvhdXNebBRwHr9Rj3id4bVfltJ8eT5/R3xY8kputklW2mrw9UfdISzAJqOPp9KZcU4K9p8g==
"""

class TapoP115Controller:
    def __init__(self, device_ip):
        self.device_ip = device_ip
        self.session_id = None
        self.token = None
    
    def perform_handshake(self):
        """Führt den ersten Handshake durch und speichert die Session-ID"""
        handshake_data = {
            "method": "handshake",
            "params": {
                "key": PUBLIC_KEY
            },
            "requestTimeMils": 0
        }
        
        headers = {
            "Referer": f"http://{self.device_ip}:80",
            "Accept": "application/json",
            "requestByApp": "true",
            "Content-Type": "application/json; charset=UTF-8"
        }
        
        response = requests.post(
            f"http://{self.device_ip}/app",
            json=handshake_data,
            headers=headers
        )
        
        if response.status_code == 200:
            data = response.json()
            if data["error_code"] == 0:
                # Session-ID aus dem Cookie extrahieren
                self.session_id = response.cookies.get("TP_SESSIONID")
                print(f"Handshake erfolgreich, Session-ID: {self.session_id}")
                
                # In einem echten Szenario würden wir hier den verschlüsselten Schlüssel entschlüsseln
                # Da wir keinen privaten Schlüssel haben, speichern wir nur die Antwort
                encrypted_key = data["result"]["key"]
                print(f"Verschlüsselter Schlüssel: {encrypted_key}")
                return True
        
        print("Handshake fehlgeschlagen")
        return False
    
    def send_command(self, encrypted_command):
        """Sendet einen vorbereiteten verschlüsselten Befehl"""
        if not self.session_id:
            print("Keine Session-ID. Bitte zuerst Handshake durchführen.")
            return None
        
        # Token aus der Wireshark-Aufnahme (könnte sich ändern, oder vom Gerät abhängen)
        token = "9DFAC92C53CEC92E67A9CB2E00B3CB2F"
        
        secure_data = {
            "method": "securePassthrough",
            "params": {
                "request": encrypted_command
            }
        }
        
        headers = {
            "Referer": f"http://{self.device_ip}:80",
            "Accept": "application/json",
            "requestByApp": "true",
            "Content-Type": "application/json; charset=UTF-8",
            "Cookie": f"TP_SESSIONID={self.session_id}"
        }
        
        response = requests.post(
            f"http://{self.device_ip}/app?token={token}",
            json=secure_data,
            headers=headers
        )
        
        if response.status_code == 200:
            data = response.json()
            if data["error_code"] == 0:
                # In einem echten Szenario würden wir die Antwort entschlüsseln
                encrypted_response = data["result"]["response"]
                print("Befehl erfolgreich gesendet")
                return encrypted_response
        
        print("Fehler beim Senden des Befehls")
        return None
    
    def turn_on(self):
        """Schaltet die Steckdose ein"""
        return self.send_command(COMMAND_ON)
    
    def turn_off(self):
        """Schaltet die Steckdose aus"""
        return self.send_command(COMMAND_OFF)

# Verwendungsbeispiel
if __name__ == "__main__":
    controller = TapoP115Controller("192.168.0.102")
    
    # Handshake durchführen
    if controller.perform_handshake():
        # Steckdose einschalten
        controller.turn_on()
        
        # Kurze Pause (im echten Code mit time.sleep)
        print("Steckdose ist eingeschaltet")
        
        # Steckdose ausschalten
        controller.turn_off()
        print("Steckdose ist ausgeschaltet")