#!/usr/bin/env python3
"""
RTSP Server для стриминга с CSI камеры на Jetson Orin.
Использует GStreamer RTSP Server.
"""

import os
import gi
gi.require_version('Gst', '1.0')
gi.require_version('GstRtspServer', '1.0')
from gi.repository import Gst, GstRtspServer, GLib

# Инициализация GStreamer
Gst.init(None)

# Параметры из environment
WIDTH = os.environ.get('CAMERA_WIDTH', '1920')
HEIGHT = os.environ.get('CAMERA_HEIGHT', '1080')
FPS = os.environ.get('CAMERA_FPS', '30')
RTSP_PORT = os.environ.get('RTSP_PORT', '8554')


def create_pipeline():
    """
    Создаёт GStreamer pipeline для CSI камеры.
    Пробуем разные источники в порядке приоритета.
    """

    # Вариант 1: nvarguscamerasrc (CSI камера на Jetson) с NVIDIA hardware encoder
    # Используем nvv4l2h264enc для аппаратного кодирования без EGL
    csi_pipeline = (
        f'nvarguscamerasrc ! '
        f'video/x-raw(memory:NVMM),width={WIDTH},height={HEIGHT},framerate={FPS}/1,format=NV12 ! '
        f'nvv4l2h264enc bitrate=4000000 preset-level=1 insert-sps-pps=true ! '
        f'h264parse ! '
        f'rtph264pay name=pay0 pt=96'
    )

    # Вариант 2: v4l2src (USB камера) с NVIDIA hardware encoder
    v4l2_pipeline = (
        f'v4l2src device=/dev/video0 ! '
        f'video/x-raw,width={WIDTH},height={HEIGHT},framerate={FPS}/1 ! '
        f'nvvidconv ! video/x-raw(memory:NVMM),format=NV12 ! '
        f'nvv4l2h264enc bitrate=4000000 preset-level=1 insert-sps-pps=true ! '
        f'h264parse ! '
        f'rtph264pay name=pay0 pt=96'
    )

    # Вариант 3: тестовый источник с software encoder (fallback)
    test_pipeline = (
        f'videotestsrc is-live=true ! '
        f'video/x-raw,width={WIDTH},height={HEIGHT},framerate={FPS}/1 ! '
        f'videoconvert ! '
        f'x264enc tune=zerolatency bitrate=4000 speed-preset=ultrafast ! '
        f'rtph264pay name=pay0 pt=96'
    )

    # Пробуем CSI камеру сначала
    try:
        test = Gst.parse_launch(csi_pipeline.replace('rtph264pay name=pay0 pt=96', 'fakesink'))
        test.set_state(Gst.State.PLAYING)
        # Даём время на инициализацию
        import time
        time.sleep(2)
        state = test.get_state(Gst.CLOCK_TIME_NONE)
        test.set_state(Gst.State.NULL)
        if state[1] == Gst.State.PLAYING:
            print("Using CSI camera (nvarguscamerasrc)")
            return csi_pipeline
    except Exception as e:
        print(f"CSI camera not available: {e}")

    # Пробуем USB камеру
    if os.path.exists('/dev/video0'):
        print("Using USB camera (v4l2src)")
        return v4l2_pipeline

    # Fallback на тестовый источник
    print("No camera found, using test source")
    return test_pipeline


class RTSPServer:
    def __init__(self):
        self.server = GstRtspServer.RTSPServer()
        self.server.set_service(RTSP_PORT)

        # Создаём factory для стрима
        factory = GstRtspServer.RTSPMediaFactory()
        pipeline = create_pipeline()
        print(f"Pipeline: {pipeline}")
        factory.set_launch(f'( {pipeline} )')
        factory.set_shared(True)

        # Добавляем mount point
        mount_points = self.server.get_mount_points()
        mount_points.add_factory('/stream', factory)

        # Запускаем сервер
        self.server.attach(None)

        print(f"\n{'='*50}")
        print(f"RTSP Server started!")
        print(f"Stream URL: rtsp://<device-ip>:{RTSP_PORT}/stream")
        print(f"{'='*50}\n")


def main():
    import signal
    import sys

    server = RTSPServer()
    loop = GLib.MainLoop()

    def signal_handler(sig, frame):
        print("Shutting down...")
        loop.quit()
        sys.exit(0)

    signal.signal(signal.SIGINT, signal_handler)
    signal.signal(signal.SIGTERM, signal_handler)

    print("RTSP server running. Waiting for connections...")
    sys.stdout.flush()

    try:
        loop.run()
    except Exception as e:
        print(f"Error in main loop: {e}")
        sys.exit(1)


if __name__ == '__main__':
    main()
