from ctypes import POINTER, c_int, cast, string_at
from typing import List, Union

from mudra_sdk.models.computation_wrapper import ComputationWrapper
from mudra_sdk.models.enums import EventType, RecordingDataType


class DataRecorder:
    def __init__(self):
        pass

    def enable_recording(self, computation_wrapper: ComputationWrapper) -> None:
        computation_wrapper.enable_recording()

    def disable_recording(self, computation_wrapper: ComputationWrapper) -> None:
        computation_wrapper.disable_recording()

    def start_recording( self, computation_wrapper: ComputationWrapper, information_json_string: str, recording_types: List[RecordingDataType], record_time: int) -> None:
        int_array = (c_int * len(recording_types))()
        for i in range(len(recording_types)):
            int_array[i] = recording_types[i].value
            
        recording_types_ptr = cast(int_array, POINTER(c_int))
        computation_wrapper.start_recording(  information_json_string,  recording_types_ptr,  len(recording_types), record_time)

    def stop_recording(self, computation_wrapper: ComputationWrapper) -> None:
        computation_wrapper.stop_recording()

    def get_json_recording(self, computation_wrapper: ComputationWrapper) -> str:
        buffer = computation_wrapper.fill_json_buffer()
        if not buffer:
            # Optionally use a logger here if available
            print("Failed to allocate buffer")
            return ""
        # buffer is a void pointer (memory address) - read the UTF-8 string from it
        result = string_at(buffer).decode("utf-8")
        computation_wrapper.free_shared_buffer(buffer)
        return result

    def is_recording_enabled(self, computation_wrapper: ComputationWrapper) -> bool:
        return computation_wrapper.is_recording_enabled()

    def record_event(self, computation_wrapper: ComputationWrapper, event_type: EventType, event: str) -> None:
        computation_wrapper.record_event(event_type, event)

    def record_pressure(self, computation_wrapper: ComputationWrapper, pressure: float) -> None:
        computation_wrapper.record_pressure(pressure)

    def add_video(self, computation_wrapper: ComputationWrapper, video_description: str, video_path: str) -> None:
        computation_wrapper.add_video(video_description, video_path)

