import pytest

from mirage.io.stream import materialize
from mirage.resource.ram import RAMResource
from mirage.types import MountMode
from mirage.workspace import Workspace
from mirage.workspace.executor.builtins.script import handle_source
from mirage.workspace.session.session import Session


@pytest.mark.asyncio
async def test_source_without_a_filename_is_a_usage_error():
    out, io, node = await handle_source(None, None, "",
                                        Session(session_id="s1"))
    assert out is None
    assert io.exit_code == 2
    assert b"filename argument required" in (await materialize(io.stderr))
    assert node.command == "source"


@pytest.mark.asyncio
async def test_source_runs_the_file_in_the_calling_shell():
    ws = Workspace({"/data": (RAMResource(), MountMode.WRITE)},
                   mode=MountMode.WRITE)
    await ws.execute("printf 'X=from_file\\necho arg1=$1\\n' > /data/s.sh")
    r = await ws.execute("source /data/s.sh one; echo X=$X")
    assert r.exit_code == 0
    assert r.stdout == b"arg1=one\nX=from_file\n"


@pytest.mark.asyncio
async def test_source_reports_a_missing_file():
    ws = Workspace({"/data": (RAMResource(), MountMode.WRITE)},
                   mode=MountMode.WRITE)
    r = await ws.execute("source /data/nope.sh")
    assert r.exit_code == 1
    assert b"No such file or directory" in r.stderr
