#!/usr/bin/env python3
"""
Basic usage example for UmaDB Python client.

This example demonstrates:
1. Connecting to a UmaDB server
2. Appending events
3. Reading events
4. Using queries to filter events
5. Using append conditions
"""
import uuid

from umadb import Client, Event, Query, QueryItem, AppendCondition, IntegrityError


def main():
    # Connect to UmaDB server (make sure server is running)
    print("Connecting to UmaDB server...")
    client = Client("http://localhost:50051")

    # Get current head position
    head = client.head()
    print(f"Current head position: {head}")

    # Create and append some events
    print("\nAppending events...")
    events = [
        Event(
            event_type="UserCreated",
            data=b'{"user_id": "123", "name": "Alice"}',
            tags=["user", "user:123"],
        ),
        Event(
            event_type="UserUpdated",
            data=b'{"user_id": "123", "email": "alice@example.com"}',
            tags=["user", "user:123"],
        ),
        Event(
            event_type="OrderCreated",
            data=b'{"order_id": "456", "user_id": "123"}',
            tags=["order", "user:123", "order:456"],
        ),
    ]

    position = client.append(events)
    print(f"Events appended, last position: {position}")

    # Read all events
    print("\nReading all events...")
    all_events = client.read()
    for seq_event in all_events:
        print(f"  Position {seq_event.position}: {seq_event.event.event_type} - tags: {seq_event.event.tags}")

    # Read with query to filter events
    print("\nReading user-related events...")
    user_query_item = QueryItem(tags=["user"])
    user_query = Query(items=[user_query_item])
    user_events = client.read(query=user_query)
    for seq_event in user_events:
        print(f"  Position {seq_event.position}: {seq_event.event.event_type}")

    # Read with multiple filters (OR logic)
    print("\nReading UserCreated OR OrderCreated events...")
    query = Query(items=[
        QueryItem(types=["UserCreated"]),
        QueryItem(types=["OrderCreated"]),
    ])
    filtered_events = client.read(query=query)
    for seq_event in filtered_events:
        print(f"  Position {seq_event.position}: {seq_event.event.event_type}")

    # Read with limit
    print("\nReading last 2 events...")
    recent_events = client.read(limit=2, backwards=True)
    for seq_event in recent_events:
        print(f"  Position {seq_event.position}: {seq_event.event.event_type}")

    # Try conditional append (preventing duplicate UserCreated for user:123)
    print("\nTrying conditional append (should fail)...")
    fail_query = Query(items=[
        QueryItem(types=["UserCreated"], tags=["user:123"])
    ])
    condition = AppendCondition(fail_if_events_match=fail_query)

    duplicate_event = Event(
        event_type="UserCreated",
        data=b'{"user_id": "123", "name": "Alice Again"}',
        tags=["user", "user:123"],
    )

    try:
        client.append([duplicate_event], condition=condition)
        print("  Unexpected: append succeeded")
    except IntegrityError as e:
        print(f"  Expected: append failed - {e}")

    # Conditional append that should succeed
    print("\nTrying conditional append for new user (should succeed)...")
    new_user_id = str(uuid.uuid4())
    new_user_event = Event(
        event_type="UserCreated",
        data=b'{"user_id": "456", "name": "Bob"}',
        tags=["user", new_user_id],
    )
    fail_query = Query(items=[
        QueryItem(types=["UserCreated"], tags=[new_user_id])
    ])
    condition = AppendCondition(fail_if_events_match=fail_query)

    try:
        position = client.append([new_user_event], condition=condition)
        print(f"  Success: event appended at position {position}")
    except ValueError as e:
        print(f"  Failed: {e}")

    # Final head position
    final_head = client.head()
    print(f"\nFinal head position: {final_head}")


if __name__ == "__main__":
    main()
