import pytest
from prompt_toolkit.shortcuts import CompleteStyle, PromptSession

import cmd2
from cmd2 import Completions


class AutoStyleApp(cmd2.Cmd):
    def __init__(self):
        super().__init__()

    def do_foo(self, args):
        pass

    def complete_foo(self, text, line, begidx, endidx) -> Completions:
        # Return 10 items
        items = [f"item{i}" for i in range(10) if f"item{i}".startswith(text)]
        return Completions.from_values(items)

    def do_bar(self, args):
        pass

    def complete_bar(self, text, line, begidx, endidx) -> Completions:
        # Return 5 items
        items = [f"item{i}" for i in range(5) if f"item{i}".startswith(text)]
        return Completions.from_values(items)


@pytest.fixture
def app():
    return AutoStyleApp()


def test_dynamic_complete_style(app):
    # Cmd.complete() interacts with app.active_session.
    # Set it here since it's normally set when the prompt is created.
    app.active_session: PromptSession[str] = PromptSession(
        input=app.main_session.input,
        output=app.main_session.output,
    )

    # Default max_column_completion_results is 7
    assert app.max_column_completion_results == 7

    # Complete 'foo' which has 10 items (> 7)
    # text='item', state=0, line='foo item', begidx=4, endidx=8
    app.complete("item", "foo item", 4, 8)
    assert app.active_session.complete_style == CompleteStyle.MULTI_COLUMN

    # Complete 'bar' which has 5 items (<= 7)
    app.complete("item", "bar item", 4, 8)
    assert app.active_session.complete_style == CompleteStyle.COLUMN


def test_dynamic_complete_style_custom_limit(app):
    # Cmd.complete() interacts with app.active_session.
    # Set it here since it's normally set when the prompt is created.
    app.active_session: PromptSession[str] = PromptSession(
        input=app.main_session.input,
        output=app.main_session.output,
    )

    # Change limit to 3
    app.max_column_completion_results = 3

    # Complete 'bar' which has 5 items (> 3)
    app.complete("item", "bar item", 4, 8)
    assert app.active_session.complete_style == CompleteStyle.MULTI_COLUMN

    # Change limit to 15
    app.max_column_completion_results = 15

    # Complete 'foo' which has 10 items (<= 15)
    app.complete("item", "foo item", 4, 8)
    assert app.active_session.complete_style == CompleteStyle.COLUMN
