from __future__ import annotations

from unittest.mock import Mock, create_autospec

import pytest

import dxtbx.filecache
import dxtbx.filecache_controller as fcc


def test_invalid_cache(monkeypatch):
    """Tests a condition where the filecache controller can give out an invalid cache"""

    mocklazy = create_autospec(dxtbx.filecache.lazy_file_cache)
    monkeypatch.setattr(fcc.dxtbx.filecache, "lazy_file_cache", mocklazy)

    # Create the cache
    cache = fcc.simple_controller()

    # Set up an initial, working cache
    good_file_opener = Mock()
    cache.check("working", lambda: good_file_opener)
    # This should have used the lazy_file_cache to set up
    mocklazy.assert_called_with(good_file_opener)
    mocklazy.return_value.open.assert_called()

    # Now, pass the cache an opener that fails
    badfile = Mock(side_effect=IOError("Testing bad file"))
    with pytest.raises(IOError):
        cache.check("not_working", badfile)

    # The bug: Calling check with the same tag shouldn't use the invalid cache
    # To Test: Do the working test, but with the failed tag. If the invalid
    #          cache is used, then we won't have asked for reconstruction
    mocklazy.reset_mock()
    cache.check("not_working", lambda: good_file_opener)
    mocklazy.assert_called_with(good_file_opener)
    mocklazy.return_value.open.assert_called()
