import os
import sys
from pathlib import Path

import pytest
from clarabot_nano_common.utility.path.validate import MAX_NAME_LEN, normalize_absolute_path

from clarabot_nano_tests.testing.file import temp_path


def test_utility_path_name(tmpdir):
    d = Path(normalize_absolute_path(temp_path(tmpdir)))
    d.mkdir()
    if sys.platform.startswith("linux"):
        max_unicode_name = "é" * 9 + "f" * (MAX_NAME_LEN - 18)  # utf-8 encoding matters actually
    else:
        max_unicode_name = "é" * 9 + "f" * (MAX_NAME_LEN - 9)
    for max_name in [
        "f" * MAX_NAME_LEN,
        "." + "f" * (MAX_NAME_LEN - 1),
        "." + "f" * (MAX_NAME_LEN - 6) + ".ffff",
        max_unicode_name,
    ]:
        f_max = d / max_name
        assert not f_max.exists()
        f_max.write_bytes(content := os.urandom(16))
        assert f_max.is_file()
        assert f_max.read_bytes() == content

        over_max_name = max_name[:10] + "x" + max_name[10:]
        f_over_max = d / over_max_name
        if sys.platform.startswith("win"):  # windows does not raise for checking exists on invalid-length filename
            assert f_over_max.exists() is False
            assert f_over_max.is_file() is False
        else:
            with pytest.raises(OSError):
                f_over_max.exists()
            with pytest.raises(OSError):
                f_over_max.is_file()
        with pytest.raises(OSError):
            f_over_max.write_bytes(b"xy")
        with pytest.raises(OSError):
            f_over_max.read_bytes()

        d_max = f_max.with_name(f_max.name.replace("f", "d"))
        assert not d_max.exists()
        d_max.mkdir()
        assert d_max.is_dir()
        assert list(d_max.iterdir()) == []

        f_over_max = f_over_max.with_name(f_over_max.name.replace("f", "d"))
        if sys.platform.startswith("win"):  # windows does not raise for checking exists on invalid-length filename
            assert f_over_max.exists() is False
            assert f_over_max.is_dir() is False
        else:
            with pytest.raises(OSError):
                f_over_max.exists()
            with pytest.raises(OSError):
                f_over_max.is_dir()
        with pytest.raises(OSError):
            list(f_over_max.iterdir())
