from __future__ import annotations

import os
import subprocess
from pathlib import Path

assert os.path.abspath(Path(__file__).parent) == os.path.abspath(".")

DST = "fake_path.py"

"""
* Member names were taken from https://github.com/python/typeshed/blob/main/stdlib/pathlib.pyi (2022/12/3)
* Python version and platform switches were ignored
* __hash__ is not there but actually defined so it must be overridden to return
  hash(id(self))
"""

PROPERTIES = [
    # from PurePath
    "parts",
    "drive",
    "root",
    "anchor",
    "name",
    "suffix",
    "suffixes",
    "stem",
    "parents",
    "parent",
    # from Path
]

METHODS = [
    # from PurePath
    "__eq__",
    "__fspath__",
    "__lt__",
    "__le__",
    "__gt__",
    "__ge__",
    "__truediv__",
    "__rtruediv__",
    "__bytes__",
    "as_posix",
    "as_uri",
    "is_absolute",
    "is_reserved",
    "is_relative_to",
    "match",
    "relative_to",
    "with_name",
    "with_stem",
    "with_suffix",
    "joinpath",
    # from Path
    "__enter__",
    "__exit__",
    "stat",
    "chmod",
    "exists",
    "glob",
    "is_dir",
    "is_file",
    "is_symlink",
    "is_socket",
    "is_fifo",
    "is_block_device",
    "is_char_device",
    "iterdir",
    "lchmod",
    "lstat",
    "mkdir",
    "open",
    "readlink",
    "rename",
    "replace",
    "resolve",
    "rglob",
    "rmdir",
    "symlink_to",
    "hardlink_to",
    "touch",
    "unlink",
    "absolute",
    "expanduser",
    "read_bytes",
    "read_text",
    "samefile",
    "write_bytes",
    "write_text",
    "link_to",
    "walk",
    "owner",
    "group",
    "is_mount",
]

CLASSMETHODS = [
    # from Path
    "home",
    "cwd",
]

# if sys.platform != "win32":
# 	# These methods do "exist" on Windows, but they always raise NotImplementedError,
# 	# so it's safer to pretend they don't exist


segs: list[str] = []

segs.append(
    """# Automatically generated by .gen_fake_path_code.py

from pathlib import Path
from typing import NoReturn


class FakePath(Path):
    def __new__(cls, *args: object, **kwargs: object):
        return object.__new__(cls)
"""
)

for kind, lst in (
    ("PROPERTY", PROPERTIES),
    ("METHOD", METHODS),
    ("CLASSMETHOD", CLASSMETHODS),
):
    for name in lst:
        if kind == "PROPERTY":
            segs.append("    @property")
            segs.append(
                f"    def {name}(*args: object, **kwargs: object) -> NoReturn:"
            )
        elif kind == "CLASSMETHOD":
            segs.append("    @classmethod")
            segs.append(
                f"    def {name}(cls, *a: object, **kwa: object) -> NoReturn:"
            )
        else:
            segs.append(
                f"    def {name}(*args: object, **kwargs: object) -> NoReturn:"
            )

        segs.append(
            f'        """DO NOT USE THIS {kind}. '
            'THIS IS NOT A MEMBER OF `Rule` BUT OF `FakePath`"""'
        )
        err = "You may not use this member"
        segs.append(f'        raise NotImplementedError("{err}")\n')

# override __hash__
segs.append("    def __hash__(self) -> int:\n        return hash(id(self))")


with open(DST, "w") as f:
    f.writelines("\n".join(segs) + "\n")


assert subprocess.run(["black", "--check", "--diff", DST]).returncode == 0
