import os
import tarfile
import tempfile
from contextlib import ExitStack

import pytest

from buildstream._artifactcache.tarcache import _Tar
from buildstream import utils, ProgramNotFoundError


# Test that it 'works' - this may be equivalent to test_archive_no_tar()
# on some systems.
def test_archive_default():
    with ExitStack() as stack:
        src = stack.enter_context(tempfile.TemporaryDirectory())
        tar_dir = stack.enter_context(tempfile.TemporaryDirectory())
        scratch = stack.enter_context(tempfile.TemporaryDirectory())
        test_file = stack.enter_context(open(os.path.join(src, 'test'), 'a'))
        test_file.write('Test')

        _Tar.archive(os.path.join(tar_dir, 'test.tar'), '.', src)

        with tarfile.open(os.path.join(tar_dir, 'test.tar')) as tar:
            tar.extractall(path=scratch)

        assert os.listdir(scratch) == os.listdir(src)


def test_archive_no_tar():
    # Modify the path to exclude 'tar'
    old_path = os.environ.get('PATH')
    os.environ['PATH'] = ''

    # Ensure we can't find 'tar' or 'gtar'
    try:
        for tar in ['gtar', 'tar']:
            with pytest.raises(ProgramNotFoundError):
                utils.get_host_tool(tar)

    # Run the same test as before, this time 'tar' should not be available
        test_archive_default()

    # Reset the environment
    finally:
        os.environ['PATH'] = old_path


# Same thing as test_archive_default()
def test_extract_default():
    with ExitStack() as stack:
        src = stack.enter_context(tempfile.TemporaryDirectory())
        tar_dir = stack.enter_context(tempfile.TemporaryDirectory())
        scratch = stack.enter_context(tempfile.TemporaryDirectory())
        test_file = stack.enter_context(open(os.path.join(src, 'test'), 'a'))
        test_file.write('Test')

        with tarfile.open(os.path.join(tar_dir, 'test.tar'), 'a:') as tar:
            tar.add(src, 'contents')

        _Tar.extract(os.path.join(tar_dir, 'test.tar'), scratch)

        assert os.listdir(os.path.join(scratch, 'contents')) == os.listdir(src)


def test_extract_no_tar():
    # Modify the path to exclude 'tar'
    old_path = os.environ.get('PATH')
    os.environ['PATH'] = ''

    # Ensure we can't find 'tar' or 'gtar'
    for tar in ['gtar', 'tar']:
        with pytest.raises(ProgramNotFoundError):
            utils.get_host_tool(tar)

    # Run the same test as before, this time 'tar' should not be available
    try:
        test_extract_default()

    # Reset the environment
    finally:
        os.environ['PATH'] = old_path
