#!/usr/bin/env python3
"""
subagent_example.py — Example: Using Etlworks Agent as a subagent.

This example shows how an external orchestration agent (e.g. LangChain, CrewAI,
AutoGen, or a custom agent loop) can use the Etlworks agent as a subagent for
data integration tasks.

The pattern:
1. The orchestrator receives a high-level task from the user
2. It delegates data-integration subtasks to the Etlworks agent
3. It can call individual tools for focused operations, or use the full agent
   for complex multi-step tasks

Usage:
    export ETLWORKS_URL="https://app.etlworks.com"
    export ETLWORKS_API_KEY="your-api-key"

    python subagent_example.py

Requirements: requests (pip install requests)
"""

from etlworks_agent import EtlworksAgent


def example_tool_calling():
    """
    Example 1: Direct tool calling.

    When the orchestrator knows exactly which tool to call,
    it can invoke it directly without going through the LLM.
    This is fast, deterministic, and doesn't consume LLM tokens.
    """
    print("=" * 60)
    print("Example 1: Direct tool calling")
    print("=" * 60)

    agent = EtlworksAgent()

    # Search the knowledge base
    print("\n--- Searching knowledge base ---")
    result = agent.execute_tool("search_knowledge_base", {
        "query": "how to create a REST API connection"
    })
    print("Success:", result.get("success"))
    print("Result preview:", result.get("result", "")[:200], "...")

    # List available CLI commands
    print("\n--- Listing CLI commands ---")
    result = agent.execute_tool("host_list_commands", {})
    print("Success:", result.get("success"))
    print("Result preview:", result.get("result", "")[:200], "...")

    # Search for templates
    print("\n--- Searching templates ---")
    result = agent.execute_tool("search_templates", {
        "query": "salesforce to database"
    })
    print("Success:", result.get("success"))
    print("Result preview:", result.get("result", "")[:200], "...")


def example_one_shot_chat():
    """
    Example 2: One-shot chat (stateless).

    When the orchestrator needs the Etlworks agent to handle a
    complex question that may require multiple tool calls internally,
    it delegates the entire interaction.
    """
    print("\n" + "=" * 60)
    print("Example 2: One-shot chat")
    print("=" * 60)

    agent = EtlworksAgent()

    response = agent.chat(
        "I need to set up a daily sync from a REST API to a PostgreSQL database. "
        "What's the best approach?"
    )

    print("\nResponse:", response.get("response", "")[:500])
    if response.get("tools_used"):
        print("Tools used:", response["tools_used"])
    print("Tokens:", response.get("usage", {}))


def example_multi_turn_session():
    """
    Example 3: Multi-turn session (stateful).

    The orchestrator creates a session and sends multiple messages.
    The Etlworks agent remembers the conversation context, so later
    messages can reference earlier ones.
    """
    print("\n" + "=" * 60)
    print("Example 3: Multi-turn session")
    print("=" * 60)

    agent = EtlworksAgent()

    # Create session
    session_id = agent.create_session()
    print("Session:", session_id)

    # Turn 1: Ask about connections
    print("\n--- Turn 1 ---")
    r1 = agent.session_chat(session_id, "How do I create a REST API connection?")
    print("Response:", r1.get("response", "")[:300])

    # Turn 2: Follow up (agent remembers Turn 1)
    print("\n--- Turn 2 ---")
    r2 = agent.session_chat(session_id, "Now how do I schedule it to run every hour?")
    print("Response:", r2.get("response", "")[:300])

    # Check conversation history
    print("\n--- Session history ---")
    messages = agent.session_messages(session_id)
    for msg in messages:
        role = msg.get("role", "?")
        content = msg.get("content", "")[:100]
        print("  [%s] %s..." % (role, content))


def example_streaming():
    """
    Example 4: Streaming response.

    For real-time display in a UI or for forwarding tokens to another
    agent/user, use the streaming endpoints.
    """
    print("\n" + "=" * 60)
    print("Example 4: Streaming response")
    print("=" * 60)

    agent = EtlworksAgent()

    print("\nStreaming: ", end="", flush=True)
    for event in agent.chat_stream("What are the main features of Etlworks Integrator?"):
        if event["type"] == "token":
            print(event["content"], end="", flush=True)
        elif event["type"] == "tool_start":
            print("\n  [calling %s]" % event["tool"], end="", flush=True)
        elif event["type"] == "tool_end":
            print(" done", end="", flush=True)
        elif event["type"] == "end":
            print("\n")


def example_orchestrator_pattern():
    """
    Example 5: Orchestrator pattern.

    Shows how a custom orchestrator agent can integrate Etlworks
    as one of several subagents. The orchestrator decides which
    subagent to call based on the task type.
    """
    print("\n" + "=" * 60)
    print("Example 5: Orchestrator pattern (pseudo-code)")
    print("=" * 60)

    print("""
    # In your orchestrator agent:

    from etlworks_agent import EtlworksAgent

    etlworks = EtlworksAgent(base_url="https://app.etlworks.com", api_key="...")

    def handle_task(task):
        if task.type == "data_integration":
            # Delegate to Etlworks agent for integration tasks
            return etlworks.chat(task.description)

        elif task.type == "search_docs":
            # Use Etlworks KB search directly
            return etlworks.execute_tool("search_knowledge_base", {
                "query": task.query
            })

        elif task.type == "run_command":
            # Execute a CLI command via Etlworks
            return etlworks.execute_tool("host_cli", {
                "command": task.command
            })

        elif task.type == "import_template":
            # Search for and import a template
            search = etlworks.execute_tool("search_templates", {
                "query": task.template_query
            })
            # Parse template ID from search results, then import
            return etlworks.execute_tool("import_template", {
                "template_id": parse_template_id(search),
                "mode": "standard"
            })

        elif task.type == "complex_setup":
            # For complex multi-step setups, use the full agent
            # in a session so it can plan and execute
            session = etlworks.create_session()
            result = etlworks.session_chat(session, task.description)
            return result

    # The orchestrator can also combine Etlworks with other tools:
    # 1. Query a database schema (your own tool)
    # 2. Ask Etlworks to create a flow for that schema
    # 3. Ask Etlworks to schedule the flow
    # 4. Monitor execution (your own monitoring tool)
    """)


if __name__ == "__main__":
    import sys

    examples = {
        "tools": example_tool_calling,
        "chat": example_one_shot_chat,
        "session": example_multi_turn_session,
        "stream": example_streaming,
        "orchestrator": example_orchestrator_pattern,
    }

    if len(sys.argv) > 1 and sys.argv[1] in examples:
        examples[sys.argv[1]]()
    else:
        print("Etlworks Agent — Subagent Integration Examples")
        print()
        print("Usage: python subagent_example.py <example>")
        print()
        print("Available examples:")
        for name, func in examples.items():
            print("  %-15s %s" % (name, func.__doc__.strip().split("\n")[0]))
        print()
        print("  all             Run all examples")
        print()

        if len(sys.argv) > 1 and sys.argv[1] == "all":
            for func in examples.values():
                try:
                    func()
                except Exception as e:
                    print("[Error] %s" % e)
