import pytest
from fsspec.spec import AbstractFileSystem, AbstractBufferedFile


class DummyTestFS(AbstractFileSystem):
    protocol = "mock"
    _fs_contents = (
        {"name": "top_level/second_level/date=2019-10-01/", "type": "directory"},
        {
            "name": "top_level/second_level/date=2019-10-01/a.parquet",
            "type": "file",
            "size": 100,
        },
        {
            "name": "top_level/second_level/date=2019-10-01/b.parquet",
            "type": "file",
            "size": 100,
        },
        {"name": "top_level/second_level/date=2019-10-02/", "type": "directory"},
        {
            "name": "top_level/second_level/date=2019-10-02/a.parquet",
            "type": "file",
            "size": 100,
        },
        {"name": "top_level/second_level/date=2019-10-04/", "type": "directory"},
        {
            "name": "top_level/second_level/date=2019-10-04/a.parquet",
            "type": "file",
            "size": 100,
        },
        {"name": "misc/", "type": "directory"},
        {"name": "misc/foo.txt", "type": "file", "size": 100},
    )

    def ls(self, path, detail=True, **kwargs):
        files = (file for file in self._fs_contents if path in file["name"])

        if detail:
            return list(files)

        return list(sorted([file["name"] for file in files]))


@pytest.mark.parametrize(
    "test_path, expected",
    [
        (
            "mock://top_level/second_level/date=2019-10-01/a.parquet",
            ["top_level/second_level/date=2019-10-01/a.parquet"],
        ),
        (
            "mock://top_level/second_level/date=2019-10-01/*",
            [
                "top_level/second_level/date=2019-10-01/a.parquet",
                "top_level/second_level/date=2019-10-01/b.parquet",
            ],
        ),
        (
            "mock://top_level/second_level/date=2019-10-0[1-4]",
            [
                "top_level/second_level/date=2019-10-01",
                "top_level/second_level/date=2019-10-02",
                "top_level/second_level/date=2019-10-04",
            ],
        ),
        (
            "mock://top_level/second_level/date=2019-10-0[1-4]/*",
            [
                "top_level/second_level/date=2019-10-01/a.parquet",
                "top_level/second_level/date=2019-10-01/b.parquet",
                "top_level/second_level/date=2019-10-02/a.parquet",
                "top_level/second_level/date=2019-10-04/a.parquet",
            ],
        ),
        (
            "mock://top_level/second_level/date=2019-10-0[1-4]/[a].*",
            [
                "top_level/second_level/date=2019-10-01/a.parquet",
                "top_level/second_level/date=2019-10-02/a.parquet",
                "top_level/second_level/date=2019-10-04/a.parquet",
            ],
        ),
    ],
)
def test_glob(test_path, expected):
    test_fs = DummyTestFS()

    assert test_fs.glob(test_path) == expected


def test_cache():
    fs = DummyTestFS()
    fs2 = DummyTestFS()
    assert fs is fs2

    assert len(fs._cache) == 1
    del fs2
    assert len(fs._cache) == 1
    del fs
    assert len(DummyTestFS._cache) == 1

    DummyTestFS.clear_instance_cache()
    assert len(DummyTestFS._cache) == 0


def test_alias():
    with pytest.warns(FutureWarning, match="add_aliases"):
        DummyTestFS(add_aliases=True)


def test_add_docs_warns():
    with pytest.warns(FutureWarning, match="add_docs"):
        AbstractFileSystem(add_docs=True)


def test_cache_options():
    fs = DummyTestFS()
    f = AbstractBufferedFile(fs, "misc/foo.txt", cache_type="bytes")
    assert f.cache.trim

    # TODO: dummy buffered file
    f = AbstractBufferedFile(
        fs, "misc/foo.txt", cache_type="bytes", cache_options=dict(trim=False)
    )
    assert f.cache.trim is False

    f = fs.open("misc/foo.txt", cache_type="bytes", cache_options=dict(trim=False))
    assert f.cache.trim is False


def test_trim_kwarg_warns():
    fs = DummyTestFS()
    with pytest.warns(FutureWarning, match="cache_options"):
        AbstractBufferedFile(fs, "misc/foo.txt", cache_type="bytes", trim=False)


def test_eq():
    fs = DummyTestFS()
    result = fs == 1
    assert result is False

@@ -156,16 +156,133 @@
 nts = (%0A
+        %7B%22name%22: %22top_level%22, %22type%22: %22directory%22%7D,%0A        %7B%22name%22: %22top_level/second_level%22, %22type%22: %22directory%22%7D,%0A
         
@@ -329,17 +329,16 @@
 19-10-01
-/
 %22, %22type
@@ -702,17 +702,16 @@
 19-10-02
-/
 %22, %22type
@@ -929,17 +929,16 @@
 19-10-04
-/
 %22, %22type
@@ -1122,17 +1122,16 @@
 %22: %22misc
-/
 %22, %22type
@@ -1264,16 +1264,59 @@
 wargs):%0A
+        path = self._strip_protocol(path)%0A%0A
         
@@ -1362,20 +1362,50 @@
 ents
- if path in 
+%0A                 if path == self._parent(
 file
@@ -1413,16 +1413,17 @@
 %22name%22%5D)
+)
 %0A%0A      
@@ -1895,32 +1895,32 @@
 -01/a.parquet%22,%0A
-
                 
@@ -1999,32 +1999,140 @@
    ),%0A        (%0A
+            %22mock://top_level/second_level/date=2019-10%22,%0A            %5B%0A            %5D,%0A        ),%0A        (%0A
             %22moc

Make `ls` in the mock FS behave