import io
import json
import pathlib
from unittest import mock

import pytest

from dcoraid import cli
from dcoraid.api import errors

from .common import get_api, make_upload_task


def test_cli_basic():
    path_task = make_upload_task(resource_names=["cli_upload.rtdc"])
    api = get_api()
    uj = cli.upload_task(path_task, api.server, api.api_key, ret_job=True)
    pkg_dict = api.get("package_show", id=uj.dataset_id)
    assert pkg_dict["resources"][0]["name"] == "cli_upload.rtdc"
    assert pkg_dict["state"] == "active"


@pytest.mark.parametrize("entry,emsg",
                         [["license_id", "Please choose a license_id"],
                          ["owner_org", "A circle must be provided"],
                          ["authors", r"authors: \['Missing value'\]"],
                          ])
def test_cli_fail_if_no_entries_missing(entry, emsg):
    path_task = pathlib.Path(
        make_upload_task(resource_names=["cli_upload.rtdc"]))
    data = json.loads(path_task.read_text())
    data["dataset_dict"].pop(entry)
    path_task.write_text(json.dumps(data))
    api = get_api()
    with pytest.raises(errors.APIConflictError, match=emsg):
        cli.upload_task(path_task, api.server, api.api_key)


@mock.patch("dcoraid.upload.job.sha256sum",
            side_effect=["BAD SHA", "BAD SHA2", "BAD SHA3"])
@mock.patch('sys.stdout', new_callable=io.StringIO)
def test_cli_fail_upload(mock_stdout, mock_sha256sum):
    path_task = make_upload_task(resource_names=["cli_upload.rtdc"])
    api = get_api()
    with pytest.raises(ValueError, match="See message above!"):
        cli.upload_task(path_task, api.server, api.api_key, ret_job=True)
    stdout_printed = mock_stdout.getvalue()
    assert "SHA256 sum failed for resources" in stdout_printed
    assert "'cli_upload.rtdc' (BAD SHA vs." in stdout_printed
