from dput.util import run_command
from dput import upload
from dput.exceptions import UploadException
import dput.core
import glob
import os.path
import os
import pytest

dput.core.CONFIG_LOCATIONS = {
    os.path.abspath("./tests/dputng"): 0
}  # Isolate.


@pytest.fixture
def monkeypatch_ubuntu_supported(monkeypatch):
    """Patch the set of supported Ubuntu codenames."""
    monkeypatch.setattr(
        "distro_info.UbuntuDistroInfo.supported",
        lambda *args, **kwargs: ["xenial", "bionic", "focal", "jammy"],
    )


@pytest.fixture
def isolate_uploads(monkeypatch, tmp_path):
    """
    Isolate uploads to a temporary directory.

    We don't want uploads to go anywhere real.  Our test profiles all use
    the "local" method, but this also arranges for the uploads to end up in
    a temporary directory whose contents can then be inspected by tests.
    """
    # Take advantage of the fact that LocalUploader.upload_file calls
    # os.path.expanduser.
    def fake_expanduser(arg):
        if arg == "/dev/null":
            return str(tmp_path)
        else:
            return str(tmp_path / arg)

    monkeypatch.setattr(os.path, "expanduser", fake_expanduser)
    yield tmp_path


def _build_fnord(version='1.0'):
    popdir = os.path.abspath(os.getcwd())
    os.chdir("tests/fake_package/fake-package-%s" % version)
    cmd = "dpkg-buildpackage -us -uc -S"
    env = {
        "DEB_VENDOR": "Ubuntu",
        "DPKG_ORIGINS_DIR": "../../dpkg-origins",
        "PATH": os.environ["PATH"],
    }
    stdout, stderr, ret = run_command(cmd, env=env)
    upload_files = glob.glob("../fnord_%s_source.*.upload" % version)
    for fn in upload_files:
        os.unlink(fn)
    os.chdir(popdir)
    if ret != 0:
        print('Package build failed.')
        print(f'cmd: {cmd}')
        print(f'env: {env}')
        print('###### stdout:')
        print(stdout)
        print('###### stderr:')
        print(stderr)
        print('###### - end log')
        assert False
    return os.path.abspath("tests/fake_package/fnord_%s_source.changes"
                           % version)


def test_upload(monkeypatch_ubuntu_supported, isolate_uploads):
    """ Test the upload of a package """
    path = _build_fnord()
    upload(path, 'test')
    assert (isolate_uploads / "fnord_1.0_source.changes").exists()


def test_double_upload(monkeypatch_ubuntu_supported, isolate_uploads):
    """ Test a double-upload (and force block) """
    path = _build_fnord()
    upload(path, 'test')
    assert (isolate_uploads / "fnord_1.0_source.changes").exists()
    with pytest.raises(
        UploadException, match="Package fnord was already uploaded to test"
    ):
        upload(path, 'test')


def test_ppa_upload(monkeypatch_ubuntu_supported, isolate_uploads):
    """ Test the upload of a package to a PPA (no Launchpad-Bugs-Fixed) """
    path = _build_fnord(version='1.1')
    (isolate_uploads / "~foo/bar").mkdir(parents=True)
    upload(path, 'ppa:foo/bar')
    assert (isolate_uploads / "~foo/bar/fnord_1.1_source.changes").exists()
