import pathlib
from typing import Iterator

import pytest
from typer.testing import CliRunner

from rbx.box.testing import testing_package


@pytest.fixture
def preset_testing_pkg_from_resources(
    request,
    pkg_from_resources: pathlib.Path,
) -> Iterator[testing_package.TestingPackage]:
    marker = request.node.get_closest_marker('preset_path')
    if marker is None:
        raise ValueError('preset_path marker not found')
    preset_path = pkg_from_resources / marker.args[0]
    with testing_package.TestingPackage(preset_path) as pkg:
        yield pkg


@pytest.fixture
def preset_testing_pkg_from_testdata(
    request,
    pkg_from_testdata: pathlib.Path,
) -> Iterator[testing_package.TestingPackage]:
    marker = request.node.get_closest_marker('preset_path')
    if marker is None:
        raise ValueError('preset_path marker not found')
    preset_path = pkg_from_testdata / marker.args[0]
    with testing_package.TestingPackage(preset_path) as pkg:
        yield pkg


@pytest.mark.e2e
@pytest.mark.slow
@pytest.mark.preset_path('problem')
@pytest.mark.resource_pkg('presets/default')
def test_default_preset_problem(
    preset_testing_pkg_from_resources: testing_package.TestingPackage,
):
    from rbx.box.cli import app

    runner = CliRunner()

    # Test problem run
    result = runner.invoke(app, ['run'])
    print(result.stdout)
    assert result.exit_code == 0, 'rbx run failed'

    # Test problem unit tests
    result = runner.invoke(app, ['unit'])
    print(result.stdout)
    assert result.exit_code == 0, 'rbx unit failed'

    # Test problem build statement
    result = runner.invoke(app, ['st', 'b'])

    print(result.stdout)
    assert result.exit_code == 0, 'rbx st b failed'

    # Package to BOCA
    result = runner.invoke(app, ['pkg', 'boca'])
    print(result.stdout)
    assert result.exit_code == 0, 'rbx pkg boca failed'

    # Package to Polygon
    result = runner.invoke(app, ['pkg', 'polygon'])
    print(result.stdout)
    assert result.exit_code == 0, 'rbx pkg polygon failed'


@pytest.mark.e2e
@pytest.mark.slow
@pytest.mark.preset_path('')
@pytest.mark.test_pkg('problems/interactive')
def test_interactive_problem(
    preset_testing_pkg_from_testdata: testing_package.TestingPackage,
):
    from rbx.box.cli import app

    runner = CliRunner()

    # Test problem run
    result = runner.invoke(app, ['run'])
    print(result.stdout)
    assert result.exit_code == 0, 'rbx run failed'
    assert 'FAILED' not in result.stdout
