# Copyright (c) 2026 동일비전(Dongil Vision Korea). All Rights Reserved.
"""sm_infra 공통 기반 — SharedMemory 리소스 관리 + 유틸리티

- _ShmBase: 모든 SHM 클래스의 공통 베이스
- safe_shm_close: close + 조건부 unlink (owner 전용)
- cleanup_existing_shm: 잔류 SHM 안전 제거 (재시작 시)
"""

import warnings
from multiprocessing.shared_memory import SharedMemory


# ─── SHM 유틸리티 ─────────────────────────────────────────────

def safe_shm_close(shm: SharedMemory, is_owner: bool):
    """SharedMemory 안전 종료 (owner일 때 unlink 포함).

    Args:
        shm: 닫을 SharedMemory 인스턴스
        is_owner: True면 unlink까지 수행 (creator)
    """
    try:
        shm.close()
    except Exception:
        pass
    if is_owner:
        try:
            shm.unlink()
        except FileNotFoundError:
            pass
        except PermissionError:
            warnings.warn(
                f"SHM unlink failed (in use): {shm.name}",
                ResourceWarning, stacklevel=3
            )


def cleanup_existing_shm(name: str):
    """기존 잔류 SharedMemory 안전 제거 (재시작 시 사용).

    Args:
        name: SharedMemory 이름
    """
    try:
        old = SharedMemory(name=name)
        old.close()
        old.unlink()
    except Exception:
        pass


# ─── SHM 기반 공통 베이스 ─────────────────────────────────────

class _ShmBase:
    """SharedMemory 리소스를 소유하는 모든 sm_infra 클래스의 기반.

    제공 기능:
      - _init_shm(): SharedMemory 생성/연결 + 공통 필드 초기화
      - close(): safe_shm_close 위임 (중복 호출 방지)
      - __enter__/__exit__: with 문 지원
      - name property
    """
    __slots__ = ('_name', '_shm', '_is_new', '_closed')

    def _init_shm(self, name: str, size: int, create: bool):
        self._name = name
        self._is_new = create
        self._closed = False
        self._shm = SharedMemory(name=name, create=create, size=size)

    @property
    def name(self) -> str:
        return self._name

    def close(self):
        if self._closed:
            return
        self._closed = True
        safe_shm_close(self._shm, self._is_new)

    def __del__(self):
        try:
            self.close()
        except Exception:
            pass

    def __enter__(self):
        return self

    def __exit__(self, *_):
        self.close()
