import json
from pathlib import Path
import os
from feathersdk.utils.common import currtime
from feathersdk.utils.feathertypes import Dict, Any

def write_json_file(data: Dict[str, Any], file_path: str) -> None:
    """
    Writes a Python dictionary to a file as JSON.

    Args:
        data (dict): Dictionary to write.
        file_path (str): File path to write to (default: 'canstate.txt').
    """
    path = Path(file_path)
    with path.open("w", encoding="utf-8") as f:
        json.dump(data, f, ensure_ascii=False, indent=2)

def read_json_file(file_path: str) -> Dict[str, Any]:
    """
    Reads a JSON dictionary from a file.

    Args:
        file_path (str): Path to the file to read.

    Returns:
        dict: The parsed dictionary.

    Raises:
        FileNotFoundError: If the file does not exist.
        json.JSONDecodeError: If the file contains invalid JSON.
    """
    path = Path(file_path)
    with path.open("r", encoding="utf-8") as f:
        ret = json.load(f)
        if not isinstance(ret, dict):
            raise ValueError(f"File {file_path} contains invalid JSON: {ret}")
        return ret

def release_file_lock(lock_path: str) -> None:
    try:
        os.remove(lock_path)
    except OSError:
        pass

class FileLock:
    def __init__(self, lock_path: str):
        self.lock_path = lock_path
        self.has_forced_overtake_lock = os.path.exists(self.lock_path)
        self._currtime_string = str(currtime())
        self._write_lock()

    def _write_lock(self):
        with open(self.lock_path, "w") as f:
            f.write(self._currtime_string)

    def is_lock_owned(self) -> bool:
        if not os.path.exists(self.lock_path):
            return False

        try:
            with open(self.lock_path, "r") as f:
                contents = f.read().strip()
            return contents == self._currtime_string
        except OSError:
            return False
    
    def release(self) -> None:
        release_file_lock(self.lock_path)
