#!/usr/bin/env python3
"""
Live HLS Broadcast Server v4
Based on v1 but with 60 segments (perfect loop, no 3.1s segment)
Port 9004
"""

import http.server
import socketserver
import ssl
import time
import threading
from datetime import datetime

PORT = 9004
SSL_CERT = '/etc/letsencrypt/live/cdn-srt.smartbit.co/fullchain.pem'
SSL_KEY = '/etc/letsencrypt/live/cdn-srt.smartbit.co/privkey.pem'
SEGMENT_DURATION = 6  # seconds
TOTAL_SEGMENTS = 60
TOTAL_DURATION = 360  # seconds (60 * 6)
WINDOW_SIZE = 12  # segments in live window

# SCTE-35 marker positions
SCTE35_CUE_OUT_SEGMENT = 18  # Shifted to allow buffer at end
SCTE35_CUE_IN_SEGMENT = 58   # Ends at 58, leaving 59 as buffer
SCTE35_DURATION = 240.0      # 40 segments * 6s = 240s

class LivePlaylistGenerator:
    def __init__(self):
        self.start_time = time.time()
        self.lock = threading.Lock()

    def get_current_segment(self):
        """Calculate which segment should be current based on elapsed time"""
        elapsed = time.time() - self.start_time
        # Loop the content
        position_in_loop = elapsed % TOTAL_DURATION

        # Calculate segment number
        segment_num = int(position_in_loop / SEGMENT_DURATION)
        if segment_num >= TOTAL_SEGMENTS:
            segment_num = TOTAL_SEGMENTS - 1

        return segment_num

    def get_media_sequence(self):
        """Get current media sequence number"""
        elapsed = time.time() - self.start_time
        return int(elapsed / SEGMENT_DURATION)

    def generate_playlist(self, variant):
        """Generate live HLS playlist for a variant"""
        current_seg = self.get_current_segment()
        media_seq = self.get_media_sequence()

        # Calculate window start
        window_start = max(0, current_seg - WINDOW_SIZE + 1)

        lines = [
            '#EXTM3U',
            '#EXT-X-VERSION:6',
            '#EXT-X-TARGETDURATION:6',
            f'#EXT-X-MEDIA-SEQUENCE:{media_seq - (current_seg - window_start)}',
            '#EXT-X-INDEPENDENT-SEGMENTS',
        ]

        # Add segments in window
        for seg_num in range(window_start, current_seg + 1):
            actual_seg = seg_num % TOTAL_SEGMENTS
            # All segments are 6s in v4
            duration = SEGMENT_DURATION

            # Add SCTE-35 CUE-OUT marker
            if actual_seg == SCTE35_CUE_OUT_SEGMENT:
                lines.append(f'#EXT-X-CUE-OUT:DURATION={SCTE35_DURATION}')

            # Add SCTE-35 CUE-IN marker
            if actual_seg == SCTE35_CUE_IN_SEGMENT:
                lines.append('#EXT-X-CUE-IN')

            lines.append(f'#EXTINF:{duration:.6f},')
            lines.append(f'segment_{variant}_{actual_seg:03d}.ts')

        return '\n'.join(lines) + '\n'

    def generate_master_playlist(self):
        """Generate master playlist"""
        return '''#EXTM3U
#EXT-X-VERSION:3
#EXT-X-STREAM-INF:BANDWIDTH=3700000,RESOLUTION=1920x1080,CODECS="avc1.640028,mp4a.40.2"
playlist_1080p.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=2700000,RESOLUTION=1280x720,CODECS="avc1.640028,mp4a.40.2"
playlist_720p.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=1200000,RESOLUTION=854x480,CODECS="avc1.640028,mp4a.40.2"
playlist_480p.m3u8
'''

playlist_gen = LivePlaylistGenerator()

class LiveBroadcastHandler(http.server.SimpleHTTPRequestHandler):
    def do_GET(self):
        # Handle playlist requests
        if self.path == '/master.m3u8':
            content = playlist_gen.generate_master_playlist()
            self.send_response(200)
            self.send_header('Content-Type', 'application/vnd.apple.mpegurl')
            self.send_header('Cache-Control', 'no-cache, no-store, must-revalidate')
            self.send_header('Access-Control-Allow-Origin', '*')
            self.end_headers()
            self.wfile.write(content.encode())

        elif self.path == '/playlist_1080p.m3u8':
            content = playlist_gen.generate_playlist('1080p')
            self.send_response(200)
            self.send_header('Content-Type', 'application/vnd.apple.mpegurl')
            self.send_header('Cache-Control', 'no-cache, no-store, must-revalidate')
            self.send_header('Access-Control-Allow-Origin', '*')
            self.end_headers()
            self.wfile.write(content.encode())

        elif self.path == '/playlist_720p.m3u8':
            content = playlist_gen.generate_playlist('720p')
            self.send_response(200)
            self.send_header('Content-Type', 'application/vnd.apple.mpegurl')
            self.send_header('Cache-Control', 'no-cache, no-store, must-revalidate')
            self.send_header('Access-Control-Allow-Origin', '*')
            self.end_headers()
            self.wfile.write(content.encode())

        elif self.path == '/playlist_480p.m3u8':
            content = playlist_gen.generate_playlist('480p')
            self.send_response(200)
            self.send_header('Content-Type', 'application/vnd.apple.mpegurl')
            self.send_header('Cache-Control', 'no-cache, no-store, must-revalidate')
            self.send_header('Access-Control-Allow-Origin', '*')
            self.end_headers()
            self.wfile.write(content.encode())

        else:
            # Serve static files (segments)
            super().do_GET()

    def log_message(self, format, *args):
        # Log with timestamp (minimal logging for v4)
        pass

if __name__ == '__main__':
    with socketserver.TCPServer(("", PORT), LiveBroadcastHandler) as httpd:
        # Wrap with SSL
        context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
        context.load_cert_chain(SSL_CERT, SSL_KEY)
        httpd.socket = context.wrap_socket(httpd.socket, server_side=True)

        print(f"=" * 60)
        print(f"Live HLS Broadcast Server V4 Started (HTTPS)")
        print(f"Port: {PORT}")
        print(f"Segments: {TOTAL_SEGMENTS} (No 3.1s tail)")
        print(f"=" * 60)
        httpd.serve_forever()
