import os
import shutil
import tempfile
from pathlib import Path


def safe_replace_file(target: Path, data: bytes):
    """
    Create a file and replace an other with it. The operation shall not leave the target file in an undefined state.
    """
    try:
        fd, temp_path = tempfile.mkstemp(dir=target.parent, text=False)
    except PermissionError:
        fd, temp_path = tempfile.mkstemp(text=False)
    try:
        with os.fdopen(fd, "wb") as f:
            f.write(data)
        try:
            os.replace(temp_path, target)
        except OSError:
            shutil.copy2(temp_path, target)
    finally:
        try:
            os.unlink(temp_path)
        except OSError:
            pass


def temporary_file_by_target(target: Path, prefix_tag="CbN") -> str:
    """
    Create a temporary file in the target's directory and return its name.
    """
    left, _, right = target.name.rpartition(".")
    if left:
        prefix = f".~{prefix_tag}.{left}."
        suffix = f".{right}#"
    else:
        prefix = f".~{prefix_tag}.{right}."
        suffix = "#"
    fd, temp_path = tempfile.mkstemp(suffix, prefix, target.parent)
    os.close(fd)
    return os.path.basename(temp_path)
