from django.core.management.base import BaseCommand
import logging
import cv2  # OpenCV for handling RTSP streams
from myprofile.models import Camera
import json
from datetime import datetime
import os
from django.conf import settings
import time
from multiprocessing import Process
from django.db import close_old_connections

logger = logging.getLogger(__name__)

class Command(BaseCommand):
    help = 'Logs the status of RTSP connections for all cameras'

    def handle(self, *args, **kwargs):
        while True:  # Loop indefinitely
            close_old_connections()  # Close old database connections before starting new processes
            cameras = Camera.objects.filter(is_enabled=True).order_by('created_at')

            processes = []  # Keep track of the processes so we can terminate them later.

            try:
                for device in cameras:
                    print(f"devices: {device.id}")
                    # Start a new process for each device.
                    process = Process(target=self.log_camera_status, args=(device.id,))
                    processes.append(process)
                    process.start()            

                print(f"Started {len(processes)} processes.")
                
                # Let the processes run for 10 seconds
                time.sleep(300)

            except Exception as e:
                print(f"Error occurred: {str(e)}")

            finally:
                # Terminate all the processes after 10 seconds
                for process in processes:
                    if process.is_alive():
                        process.terminate()  # Terminate the process
                        process.join()  # Ensure the process has finished
                        print(f"Terminated process for camera {device.id}")

                print("Restarting processes...")

                # Wait briefly before restarting to ensure all processes are fully terminated
                time.sleep(2)

    def log_camera_status(self, camera_id):
        """
        Logs the status of a single camera's RTSP connection
        """
        try:
            close_old_connections()
            camera = Camera.objects.filter(id=camera_id).first()
            print("camera_name-----------------------------",camera.id,camera.rtsp_url)
            log_entry = {
                'camera_id': camera.id,
                'camera_name': camera.camera_name,
                'time': datetime.now().isoformat(),
                'rtsp_url': camera.rtsp_url,
                'status': 'Failed',
                'message': '',
                'generated_date': str(datetime.now().date()),
            }

            try:
                # Try to open the RTSP stream
                cap = cv2.VideoCapture(camera.rtsp_url)
                if cap.isOpened():
                    ret, _ = cap.read()
                    print("camera_name in ret-----------------------------",camera.id,camera.rtsp_url)
                    if ret:
                        print("successs-----------------------------",camera.id,camera.rtsp_url)
                        log_entry['status'] = 'Success'
                        log_entry['message'] = 'Camera connection successful.'
                    else:
                        print("Failureeeee-----------------------------",camera.id,camera.rtsp_url)
                        log_entry['message'] = f'Failed to read stream: {camera.rtsp_url}'
                else:
                    log_entry['message'] = f'Failed to connect: {camera.rtsp_url}'
                cap.release()
            except Exception as e:
                log_entry['message'] = str(e)

            self.write_log_file(log_entry)
        finally:
            # Explicitly close the database connection for the current process
            close_old_connections()

    def write_log_file(self, new_entries):
        """
        Write the log entries to a file in JSON format
        """
        log_file_path = os.path.join(settings.BASE_DIR, 'myprofile/logs', 'rtsp_logfile.json')

        # Load existing logs
        if os.path.exists(log_file_path):
            # Read the existing logs first
            with open(log_file_path, 'r+') as f:
                try:
                    existing_logs = json.load(f)
                except json.JSONDecodeError:
                    existing_logs = []
        else:
            existing_logs = []

        # Append new entries to existing logs
        existing_logs.append(new_entries)

        # Write all logs back to the file
        with open(log_file_path, 'w') as f:
                json.dump(existing_logs, f, indent=4)

        logger.info(f"Camera: {new_entries['camera_name']}, Status: {new_entries['status']}, Message: {new_entries['message']}")
