#!/usr/bin/env python3
"""HTTP server with Range request support for audio streaming."""

import os
from http.server import HTTPServer, SimpleHTTPRequestHandler

MIME_OVERRIDES = {'.m4a': 'audio/mp4', '.srt': 'text/plain'}

class RangeHandler(SimpleHTTPRequestHandler):

    def do_GET(self):
        path = self.translate_path(self.path)

        if not os.path.isfile(path):
            return super().do_GET()

        range_header = self.headers.get('Range')
        file_size = os.path.getsize(path)
        ext = os.path.splitext(path)[1].lower()
        ctype = MIME_OVERRIDES.get(ext) or self.guess_type(path)

        if not range_header:
            # Normal response but with Accept-Ranges
            self.send_response(200)
            self.send_header('Content-Type', ctype)
            self.send_header('Content-Length', str(file_size))
            self.send_header('Accept-Ranges', 'bytes')
            self.send_header('Access-Control-Allow-Origin', '*')
            self.end_headers()
            with open(path, 'rb') as f:
                self.copyfile(f, self.wfile)
            return

        # Parse range
        try:
            range_spec = range_header.replace('bytes=', '')
            parts = range_spec.split('-')
            start = int(parts[0]) if parts[0] else 0
            end = int(parts[1]) if parts[1] else file_size - 1
            end = min(end, file_size - 1)
            length = end - start + 1
        except (ValueError, IndexError):
            self.send_error(416)
            return

        self.send_response(206)
        self.send_header('Content-Type', ctype)
        self.send_header('Content-Range', f'bytes {start}-{end}/{file_size}')
        self.send_header('Content-Length', str(length))
        self.send_header('Accept-Ranges', 'bytes')
        self.send_header('Access-Control-Allow-Origin', '*')
        self.end_headers()

        with open(path, 'rb') as f:
            f.seek(start)
            remaining = length
            buf_size = 65536
            while remaining > 0:
                chunk = f.read(min(buf_size, remaining))
                if not chunk:
                    break
                self.wfile.write(chunk)
                remaining -= len(chunk)

    def end_headers(self):
        # Don't double-add Accept-Ranges
        super().end_headers()


if __name__ == '__main__':
    port = 9123
    print(f"http://0.0.0.0:{port}")
    HTTPServer(('0.0.0.0', port), RangeHandler).serve_forever()
