"""Tools to let Solveit view tmux buffers"""

# AUTOGENERATED! DO NOT EDIT! File to edit: ../nbs/03_tmux.ipynb.

# %% auto #0
__all__ = ['default_tmux_lines', 'shell_ret', 'set_default_history', 'pane', 'list_panes', 'panes', 'list_windows', 'windows',
           'list_sessions', 'sessions', 'flatten_dict']

# %% ../nbs/03_tmux.ipynb #fa3a67d2
from fastcore.utils import *
from fastcore.meta import delegates
from toolslm.funccall import *
import subprocess

# %% ../nbs/03_tmux.ipynb #b645071b
def _ssh(
    host:str=None,     # Optional SSH Host
    ip:str=None,       # Optional SSH IP
    user:str=None,     # Optional SSH user
    keyfile:str=None   # Optional SSH keyfile
): pass

# %% ../nbs/03_tmux.ipynb #ce1ccf48
@delegates(_ssh)
def shell_ret(cmd:str, capture_output: bool=True, text: bool=True, ret: bool=True, **kwargs):
    "Run shell command locally or over ssh (use host for alias, or ip/user/keyfile)"
    host, ip, user, keyfile = kwargs.pop('host', None), kwargs.pop('ip', None), kwargs.pop('user', None), kwargs.pop('keyfile', None)
    if host: cmd = f"echo '{cmd}' | ssh -A {host} 'bash -ls'"
    elif ip: cmd = f"echo '{cmd}' | ssh {f'-i {keyfile} ' if keyfile else ''}-A {user}@{ip} 'bash -ls'"
    o = subprocess.run(cmd, shell=True, text=text, capture_output=capture_output, **kwargs)
    return (o.stdout or o.stderr) if ret else o

# %% ../nbs/03_tmux.ipynb #f2b0ebde
default_tmux_lines = 500

def set_default_history(n:int):
    'Set the default number of lines to capture from tmux history'
    global default_tmux_lines
    default_tmux_lines = n

# %% ../nbs/03_tmux.ipynb #0ba9f132
@llmtool
@delegates(shell_ret)
def pane(
    n:int=None, # Number of scrollback lines to capture, in addition to visible area (None uses default_tmux_lines, which is 500 if not otherwise set)
    pane:int=None,     # Pane number to capture from
    session:str=None,  # Session name to target
    window:int=None,   # Window number to target
    **kwargs
):
    'Grab the tmux history in plain text'
    if n is None: n = default_tmux_lines
    target = session or ''
    if window is not None: target = f'{target}:{window}' if target else f':{window}'
    if pane is not None: target = f'{target}.{pane}' if target else f'.{pane}'
    cmd = f'tmux capture-pane -p -S -{n}'
    if target: cmd += f' -t {target}'
    return shell_ret(cmd, **kwargs).strip()

# %% ../nbs/03_tmux.ipynb #2376176e
@llmtool
@delegates(shell_ret)
def list_panes(
    session:str=None,  # Session name to list panes from
    window:int=None,   # Window number to list panes from
    **kwargs
):
    'List panes for a session/window (or current if none specified)'
    target = session or ''
    if window is not None: target = f'{target}:{window}' if target else f':{window}'
    cmd = f'tmux list-panes{" -t " + target if target else ""}'
    return shell_ret(cmd, **kwargs)

# %% ../nbs/03_tmux.ipynb #e11cd004
@delegates(shell_ret)
def _pane_data(line, n, session, window, **kwargs):
    pane_num = int(line.split(':')[0])
    return (pane_num, pane(n=n, pane=pane_num, session=session, window=window, **kwargs))

@llmtool
@delegates(shell_ret)
def panes(
    session:str=None,  # Session name to target
    window:int=None,   # Window number to target
    n:int=None,        # Number of scrollback lines to capture
    **kwargs
):
    'Grab history from all panes in a session/window'
    if n is None: n = default_tmux_lines
    panes_info = list_panes(session=session, window=window, **kwargs).strip().split('\n')
    return dict(_pane_data(line, n, session, window, **kwargs) for line in panes_info)

# %% ../nbs/03_tmux.ipynb #bee15f75
@llmtool
@delegates(shell_ret)
def list_windows(
    session:str=None,  # Session name to list windows from
    **kwargs
):
    'List all windows in a session'
    cmd = f'tmux list-windows{" -t " + session if session else ""}'
    return shell_ret(cmd, **kwargs)

# %% ../nbs/03_tmux.ipynb #9ad1ef87
@delegates(shell_ret)
def _window_data(line, n, session, **kwargs):
    parts = line.split(':')
    win_num = int(parts[0])
    win_name = parts[1].split('[')[0].strip().rstrip('*-')
    return (f'{win_num}:{win_name}', panes(session=session, window=win_num, n=n, **kwargs))

@llmtool
@delegates(shell_ret)
def windows(
    session:str=None,  # Session name to target
    n:int=None,        # Number of scrollback lines to capture
    **kwargs
):
    'Grab history from all panes in all windows of a session'
    windows_info = list_windows(session, **kwargs).strip().split('\n')
    return dict(_window_data(line, n, session, **kwargs) for line in windows_info)

# %% ../nbs/03_tmux.ipynb #17c4031f
@llmtool
@delegates(shell_ret)
def list_sessions(**kwargs):
    'List all tmux sessions'
    return shell_ret('tmux list-sessions', **kwargs)

# %% ../nbs/03_tmux.ipynb #2d812e19
@delegates(shell_ret)
def _session_data(line, n, **kwargs):
    session_name = line.split(':')[0]
    return (session_name, windows(session=session_name, n=n, **kwargs))

@llmtool
@delegates(shell_ret)
def sessions(
    n:int=None,        # Number of scrollback lines to capture
    **kwargs
):
    'Grab history from all panes in all windows of all sessions'
    sessions_info = list_sessions(**kwargs).strip().split('\n')
    return dict(_session_data(line, n, **kwargs) for line in sessions_info)

# %% ../nbs/03_tmux.ipynb #cc4926fd
def flatten_dict(d, parent_key='', sep='//'):
    'Flatten nested dict into list of (key_path, value) tuples'
    items = []
    for k, v in d.items():
        new_key = f'{parent_key}{sep}{k}' if parent_key else k
        if isinstance(v, dict): items.extend(flatten_dict(v, new_key, sep))
        else: items.append((new_key, v))
    return items
