# ---------------------------------------------------------------------------
# basic path predicates / joins  (local filesystem only)
# ---------------------------------------------------------------------------
def is_file(path, *args, **kwargs):
    """Local-only check: True if ``path`` is an existing file."""
    if path:
        return os.path.isfile(path)
    return False


def is_dir(path, *args, **kwargs):
    """Local-only check: True if ``path`` is an existing directory."""
    if path:
        return os.path.isdir(path)
    return False


def join_path(directory, basename):
    """Join two path components with ``os.path.join``."""
    return os.path.join(directory, basename)


def get_files(directory):
    """Recursively collect every file path under ``directory``."""
    file_list = []
    for root, _dirs, files in os.walk(directory):
        for file in files:
            file_list.append(os.path.join(root, file))
    return file_list


def get_directory(directory):
    """Return ``directory``, creating it (and parents) if it does not exist."""
    if not os.path.isdir(directory):
        os.makedirs(directory, exist_ok=True)
    return directory


def get_dirlist(directory):
    """
    Return the contents of ``directory``.

    The directory is created if missing.  If ``directory`` happens to be a file,
    a single-element list with its basename is returned.
    """
    path = get_directory(directory)
    if not path:
        return path
    dir_list = []
    if is_dir(path):
        dir_list = os.listdir(path)
    elif is_file(path):
        dir_list = [os.path.basename(path)]
    return dir_list

# ---------------------------------------------------------------------------
# pathlib-aware helpers  (get_home_dir / get_file_parts)
# ---------------------------------------------------------------------------
def is_pathlike(obj):
    return bool(obj) and isinstance(obj, Path)


def get_pathlib_path(obj):
    if obj and not is_pathlike(obj):
        obj = Path(obj)
    return obj


def get_str_path(obj):
    if is_pathlike(obj):
        obj = str(obj)
    return obj


def return_path(path, isPath=False):
    if isPath:
        path = get_pathlib_path(path)
    else:
        path = get_str_path(path)
    return path


def get_home_dir(path=None):
    """Return the home directory, preserving str/Path type of ``path``."""
    isPath = is_pathlike(path)
    path = path or os.getcwd()
    nupath = get_pathlib_path(path)
    home_path = nupath.home()
    return return_path(home_path, isPath=isPath)


def get_safe_basename(path=None):
    if path:
        return os.path.basename(str(path))


def get_safe_dirname(path=None):
    if path:
        isPath = is_pathlike(path)
        dirname = os.path.dirname(str(path))
        return return_path(dirname, isPath=isPath)


def get_safe_splitext(path=None, basename=None):
    basename = basename or get_safe_basename(path=path)
    if basename:
        filename, ext = os.path.splitext(str(basename))
        return filename, ext
    return None, None


def get_file_parts(path):
    """
    Decompose ``path`` into a dict of useful components: basename, filename,
    extension, and the names of the parent / grandparent / great-grandparent
    directories.
    """
    if path:
        path = str(path)
        basename = get_safe_basename(path)
        filename, ext = get_safe_splitext(basename=basename)

        dirname = get_safe_dirname(path)
        dirbase = get_safe_basename(dirname)

        parent_dirname = get_safe_dirname(dirname)
        parent_dirbase = get_safe_basename(parent_dirname)

        super_dirname = get_safe_dirname(parent_dirname)
        super_dirbase = get_safe_basename(super_dirname)

        return {
            "file_path": path,
            "dirname": dirname,
            "basename": basename,
            "filename": filename,
            "ext": ext,
            "dirbase": dirbase,
            "parent_dirname": parent_dirname,
            "parent_dirbase": parent_dirbase,
            "super_dirname": super_dirname,
            "super_dirbase": super_dirbase,
        }
