#!/usr/bin/env python3
import os
import glob
import json

# Configuration matching your system variables
TARGET_DIR = '/var/www/html/cam'
CACHE_FILE = '/var/www/html/cam/events_cache.json'
ALLOWED_EXTENSIONS = {'mpg', 'jpg', 'jpeg', 'png', 'gif', 'mkv', 'avi'}

def scan_camera_directory(base_dir):
    """
    Recursively tracks files matching ALLOWED_EXTENSIONS.
    Replicates your custom multi-level recursive 'read_a_dir' logic.
    """
    events = {}

    # os.walk automatically handles the nested folders recursively
    for root, dirs, files in os.walk(base_dir):
        print(f"{root}")
        # Skip hidden directories matching your `$f[0] == '.'` check
        dirs[:] = [d for d in dirs if not d.startswith('.')]
        
        # Calculate the prefix/label (\$l) used in your PHP implementation
        # Removes the root directory portion and converts path steps into a dash-separated string
        relative_path = os.path.relpath(root, base_dir)
        if relative_path == '.':
            label_prefix = ""
        else:
            label_prefix = relative_path.replace(os.sep, '-') + '-'

        # First Pass: Target MKV files to establish events and read duration metadata
        for f in files:
            print(f"file: {f}")
            if f.startswith('.') or not f.lower().endswith('.mkv'):
                continue

            # Event calculation matching your substring/character mapping splits
            if '-' in f:
                event_name_part = f.split('-', 1)[0]
                event_dttm = f.split('-', 1)[1][:14]
                event_key = f"{label_prefix}{event_name_part}-{event_dttm}"
                
                # Reconstruct full directory pattern paths without concatenation string errors
                event_num = event_key.split('-', 1)[1] if '-' in event_key else ""
                
                # Check for corresponding duration track files
                base_name, _ = os.path.splitext(f)
                duration_file = os.path.join(root, f"{base_name}.dur")
                duration = ""
                if os.path.isfile(duration_file):
                    try:
                        with open(duration_file, 'r') as df:
                            duration = df.read().strip()
                    except Exception:
                        pass
                
                # Resolve associated frame capture JPG lists using glob wildcards
                jpg_pattern = os.path.join(root, f"{event_num}-*.jpg")
                jpg_matches = sorted(glob.glob(jpg_pattern))

                events[event_key] = {
                    "timestamp": event_dttm,
                    "duration": duration,
                    "mkv": os.path.join(root, f),
                    "jpg": jpg_matches
                }

        # Second Pass: Track orphaned image steps that do not possess an MKV record
        for f in files:
            ext = f.split('.')[-1].lower() if '.' in f else ''
            if f.startswith('.') or ext not in ALLOWED_EXTENSIONS or ext == 'mkv':
                continue
                
            if '-' in f:
                event_name_part = f.split('-', 1)[0]
                event_dttm = f.split('-', 1)[1][:14]
                event_key = f"{label_prefix}{event_name_part}-{event_dttm}"

                if event_key not in events:
                    event_num = event_key.split('-')[-1]
                    jpg_pattern = os.path.join(root, f"{event_num}-*.jpg")
                    jpg_matches = sorted(glob.glob(jpg_pattern))

                    events[event_key] = {
                        "timestamp": event_dttm,
                        "duration": "",
                        "jpg": jpg_matches
                    }

    # Sort descending by event timestamp matching your array_multisort logic
    sorted_events = dict(sorted(events.items(), key=lambda item: item[1]['timestamp'], reverse=True))
    return sorted_events

def main():
    if not os.path.isdir(TARGET_DIR):
        print(f"Error: Directory '{TARGET_DIR}' not found!")
        return
    print(f"starting")
    # Process and build cache map
    compiled_data = scan_camera_directory(TARGET_DIR)

    # Atomic write to protect web interfaces reading cache mid-write
    temp_cache = CACHE_FILE + '.tmp'
    try:
        with open(temp_cache, 'w') as jf:
            json.dump(compiled_data, jf, indent=4)
        os.replace(temp_cache, CACHE_FILE)
        print(f"Success: Cached {len(compiled_data)} events to {CACHE_FILE}")
    except Exception as e:
        if os.path.exists(temp_cache):
            os.remove(temp_cache)
        print(f"Failed to write cache file: {e}")

if __name__ == "__main__":
    main()
