import os

import pytest

from gitubuntu.build import _symlink_paths_into_parent_dir
from gitubuntu.test_util import cwd_excursion


def test_symlink_to_parent_creation(tmpdir):
    """Test that build._symlink_paths_into_parent_dir creates correct symlinks.

    This function is used to create a symlink from ../<pkg>.orig.tar.xz
    to the downloaded file by git-ubuntu.
    """

    # restore working directory, as it would influences other tests.
    workdir = os.path.join(tmpdir, "workdir")
    os.makedirs(workdir)
    with cwd_excursion(target=workdir):

        _symlink_paths_into_parent_dir(["dir/a", "dir/b"])

        # it created a link
        assert os.path.islink("../a")
        # it's relative
        assert not os.readlink("../a").startswith("/")
        # the path matches the requested destination
        assert os.path.realpath("../a") == os.path.realpath("dir/a")
        assert os.path.realpath("../b") == os.path.realpath("dir/b")


def test_parent_symlink_same_destination(tmpdir):
    """Test that a symlink request for an already existing link to the
    same destination succeeds.
    """
    workdir = os.path.join(tmpdir, "workdir")
    os.makedirs(workdir)
    with cwd_excursion(target=workdir):
        os.symlink("workdir/dir/a", "../a")

        # same destination is ok
        _symlink_paths_into_parent_dir(["dir/a"])
        assert os.path.realpath("../a") == os.path.realpath("dir/a")


def test_parent_symlink_error_cleanup(tmpdir):
    """Test that an error during symlink creation will cleanup previously
    created links, but doesn't clean them up if they existed previously.
    """
    workdir = os.path.join(tmpdir, "workdir")
    os.makedirs(workdir)
    with cwd_excursion(target=workdir):

        os.symlink("workdir/dir/a", "../a")

        with pytest.raises(FileExistsError):
            # request to another a, which already exists -> no cleanup
            # c is created before the second a will fail -> clean up 'c'
            _symlink_paths_into_parent_dir(["dir/a", "dir/c", "dir/stuff/a"])

        # c must be cleaned up after the error
        assert not os.path.islink("../c")
        # a must not be cleaned up, it existed before
        assert os.path.islink("../a")
        assert os.path.realpath("../a") == os.path.realpath("dir/a")


def test_parent_symlink_existing_directory(tmpdir):
    """Test that an error during symlink creation will cleanup previously
    created links, but doesn't clean them up if they existed previously.
    """
    workdir = os.path.join(tmpdir, "workdir")
    os.makedirs(workdir)
    with cwd_excursion(target=workdir):

        os.makedirs("../somedir")

        with pytest.raises(FileExistsError):
            # request to somedir, which exists and is a directory
            _symlink_paths_into_parent_dir(["dir/stuff/somedir"])
