"""
Test script for the nono Python SDK.

Run this with: nono test_sdk.py -p 8080 --host 127.0.0.1
"""

import asyncio
import sys

from nono.models import Operation

from nono import (
    NonoClient,
    CallingFrame,
    OperationPushValue,
    OperationCall,
    ScriptFunc,
)


async def main():
    print("=" * 60)
    print("Testing nono Python SDK")
    print("=" * 60)

    try:
        async with NonoClient() as client:
            # Test 1: Config
            print("\n[1] Testing config_read...")
            config = await client.config_read()
            assert config.config is not None
            print(f"✓ Config: {config.config}")

            # Test 2: Entity operations
            print("\n[2] Testing entity operations...")
            await client.entity_write("test-entity", {"key": "value", "number": 42})
            entity = await client.entity_read("test-entity")
            assert entity is not None
            assert entity["key"] == "value"
            assert entity["number"] == 42
            print(f"✓ Entity read/write works: {entity}")

            # Test 3: Session creation
            print("\n[3] Testing session creation...")
            frame = CallingFrame(
                calling_entity_id="sdk-test",
                data={"initial": "data"},
                value_stack=[],
                op_stack=[],
                handler_stack=[],
            )
            session_id = await client.session_create(
                name="sdk-test-session",
                data={"test": "data"},
                frame=frame,
            )
            assert session_id is not None
            print(f"✓ Session created: {session_id}")

            # Test 4: Session data
            print("\n[4] Testing session data...")
            data = await client.session_get_data(session_id)
            assert data is not None
            assert data["test"] == "data"
            print(f"✓ Session data: {data}")

            # Test 5: Frame operations
            print("\n[5] Testing frame operations...")
            await client.frame_push_value(session_id, {"pushed": "value"})
            await client.frame_write_data(session_id, {"updated": "data"})
            frame_data = await client.frame_read_data(session_id)
            assert frame_data is not None
            assert frame_data["updated"] == "data"
            print(f"✓ Frame operations work: {frame_data}")

            # Test 6: Session deletion
            print("\n[6] Testing session deletion...")
            success = await client.session_delete(session_id)
            assert success is True
            print(f"✓ Session deleted")

            # Test 7: VM operations
            print("\n[7] Testing VM operations...")
            ops: list[Operation] = [
                OperationPushValue(value=100),
                OperationPushValue(value=200),
            ]
            frame = CallingFrame(
                calling_entity_id="vm-test",
                data={},
                value_stack=[],
                op_stack=ops,
                handler_stack=[],
            )
            session_id = await client.session_create(
                name="vm-test",
                data={},
                frame=frame,
            )

            # Execute operations
            success1 = await client.session_next(session_id)
            success2 = await client.session_next(session_id)
            assert success1 and success2
            print(f"✓ VM operations executed")

            await client.session_delete(session_id)

            # Test 8: Script execution
            print("\n[8] Testing script execution...")
            call_op = OperationCall(
                func=ScriptFunc(exe="echo", args=["SDK test passed!"])
            )
            frame = CallingFrame(
                calling_entity_id="script-test",
                data={},
                value_stack=[],
                op_stack=[call_op],
                handler_stack=[],
            )
            session_id = await client.session_create(
                name="script-test",
                data={},
                frame=frame,
            )
            success = await client.session_next(session_id)
            assert success
            print(f"✓ Script execution works")
            await client.session_delete(session_id)

            print("\n" + "=" * 60)
            print("ALL SDK TESTS PASSED! ✓")
            print("=" * 60)
            return 0

    except Exception as e:
        print(f"\n❌ TEST FAILED: {e}")
        import traceback

        traceback.print_exc()
        return 1


if __name__ == "__main__":
    exit_code = asyncio.run(main())
    sys.exit(exit_code)
