#!/usr/bin/env python3

import ctypes
import sys
import subprocess
import re
import json
import argparse

from pathlib import Path


def run_command(cmd, description=""):
    try:
        if description:
            print(f"\n{'='*50}\n[STEP] {description}\n{'='*50}")
            print(f"[CMD] {' '.join(cmd)}")
        
        result = subprocess.run(cmd, capture_output=True, text=True, check=False, encoding='utf-8', errors='replace')
        code = ctypes.c_int32(result.returncode).value
        output = result.stdout.strip()
        
        print(f"[RETURN CODE] {code}")
        print(f"[OUTPUT] {output}")
        return code == 0, output
    except Exception as e:
        print(f"[EXCEPTION] {e}")
        return False, str(e)


def login_with_saved_credentials(exe_path):
    """Login with saved credentials
    
    Returns:
        bool: True if successful, False otherwise
    """
    success, _ = run_command([str(exe_path), "--login-saved"], "Login with saved info")
    if not success:
        print("[ERROR] Login with saved info failed.")
        return False
    print("[OK] Login with saved info succeeded.")
    return True


def get_current_user(exe_path):
    """Get current user information
    
    Returns:
        bool: True if successful, False otherwise
    """
    success, output = run_command([str(exe_path), "--get-current-user"], "Get current user")
    if not success:
        print("[ERROR] Get current user failed.")
        return False
    print("[OK] Current User:")
    if output:
        try:
            user_info = json.loads(output)
            print(f"Domain: {user_info['data']['domain']}")
            print(f"Username: {user_info['data']['username']}")
        except (json.JSONDecodeError, KeyError):
            print("[ERROR] Failed to parse user info.")
            return False
    return True


def get_hmi_list(exe_path):
    """Get and display HMI list
    
    Returns:
        bool: True if successful, False otherwise
    """
    success, output = run_command([str(exe_path), "--get-hmi-list"], "Get HMI list")
    if not success:
        print("[ERROR] Get HMI List failed.")
        return False
    print("[OK] HMI List:")
    if output:
        try:
            hmi_list = json.loads(output)
            for hmi in hmi_list.get('data', []):
                status = "Online" if hmi.get('is_online') else "Offline"
                print(f"  - {hmi.get('nickname', 'N/A'):20} ({status:8}) HW Key: {hmi['hw_key']}")
        except (json.JSONDecodeError, KeyError):
            print(f"[ERROR] Failed to parse HMI list output.")
            return False
    return True


def connect_vpn(exe_path, hwkey):
    """Connect VPN to specified HMI
    
    Returns:
        bool: True if successful, False otherwise
    """
    success, output = run_command([str(exe_path), "--connect", hwkey], f"Connect VPN ({hwkey})")
    if not success:
        print("[ERROR] VPN connect failed.")
        return False
    print("[OK] VPN connected successfully.")
    if output:
        ip_pattern = re.compile(r'(\d{1,3}\.){3}\d{1,3}')
        match = ip_pattern.search(output)
        if match:
            print(f"[CONNECTED IP] {match.group(0)}")
    return True


def set_passthrough(exe_path, hwkey, ip):
    """Set passthrough configuration
    
    Returns:
        bool: True if successful, False otherwise
    """
    success, _ = run_command([str(exe_path), "--set-hmi-passthrough", hwkey, ip], 
                                  f"Set passthrough ({hwkey} -> {ip})")
    if not success:
        print("[ERROR] Set passthrough failed.")
        return False
    print("[OK] Set passthrough succeeded.")
    return True


def main():
    # Parse command line arguments
    parser = argparse.ArgumentParser(description='EA20 CLI Demo Script')
    parser.add_argument('hwkey', help='HW Key of the HMI to connect')
    parser.add_argument('ip', help='IP address for passthrough (e.g., 192.168.1.10)')
    args = parser.parse_args()
    
    hwkey = args.hwkey
    ip = args.ip
    
    # Find ea20_cli.exe in possible installation directories, or you can modify this to your specific path
    possible_paths = [
        Path("C:/Program Files (x86)/EasyAccess 2.0/ea20_cli.exe"),
        Path("D:/Program Files (x86)/EasyAccess 2.0/ea20_cli.exe"),
    ]
    
    exe_path = None
    for path in possible_paths:
        if path.exists():
            exe_path = path
            break
    
    if not exe_path:
        print(f"Error: Cannot find ea20_cli.exe in any of these locations:")
        for path in possible_paths:
            print(f"  - {path}")
        sys.exit(1)
    
    print(f"Using ea20_cli.exe from: {exe_path}")
    
    print(f"\n{'='*50}")
    print("EA20 CLI Demo Script")
    print(f"{'='*50}")
    print(f"HW Key: {hwkey}")
    print(f"Passthrough IP: {ip}")

    # Execute all steps with error handling
    if not login_with_saved_credentials(exe_path):
        sys.exit(1)
    
    if not get_current_user(exe_path):
        sys.exit(1)
    
    if not get_hmi_list(exe_path):
        sys.exit(1)
    
    if not connect_vpn(exe_path, hwkey):
        sys.exit(1)
    
    if not set_passthrough(exe_path, hwkey, ip):
        sys.exit(1)

    print(f"\n{'='*50}\nScript execution completed.\n{'='*50}")


if __name__ == "__main__":
    main()