<?php

namespace XcVm\Streaming\Delivery;

use XcVm\Core\Util\Encryption;

/**
 * HLSGenerator — h l s generator
 *
 * @package XC_VM_Streaming_Delivery
 * @author  Divarion_D <https://github.com/Divarion-D>
 * @copyright 2025-2026 Vateron Media
 * @link    https://github.com/Vateron-Media/XC_VM
 * @license AGPL-3.0 https://www.gnu.org/licenses/agpl-3.0.html
 */

class HLSGenerator {
	public static function generateHLS($rSettings, $rM3U8, $rUsername, $rPassword, $rStreamID, $rUUID, $rIP, $rIsHMAC = null, $rIdentifier = '', $rVideoCodec = 'h264', $rOnDemand = 0, $rServerID = null, $rProxyID = null) {
		if (!file_exists($rM3U8)) {
			return false;
		}
		$rSource = file_get_contents($rM3U8);
		if ($rSettings['encrypt_hls']) {
			$rKeyToken = Encryption::encrypt($rIP . '/' . $rStreamID, $rSettings['live_streaming_pass'], OPENSSL_EXTRA);
			$rSource = "#EXTM3U\n#EXT-X-KEY:METHOD=AES-128,URI=\"" . (($rProxyID ? '/' . md5($rProxyID . '_' . $rServerID . '_' . OPENSSL_EXTRA) : '')) . '/key/' . $rKeyToken . "\",IV=0x" . bin2hex(file_get_contents(STREAMS_PATH . $rStreamID . '_.iv')) . "\n" . substr($rSource, 8, strlen($rSource) - 8);
		}

		if (preg_match('/#EXT-X-MAP:URI="(.*?)"/', $rSource, $rInitMatch)) {
			$rInitSegment = $rInitMatch[1];
			if ($rIsHMAC) {
				$rInitToken = Encryption::encrypt('HMAC#' . $rIsHMAC . '/' . $rIdentifier . '/' . $rIP . '/' . $rStreamID . '/' . $rInitSegment . '/' . $rUUID . '/' . SERVER_ID . '/' . $rVideoCodec . '/' . $rOnDemand, $rSettings['live_streaming_pass'], OPENSSL_EXTRA);
			} else {
				$rInitToken = Encryption::encrypt($rUsername . '/' . $rPassword . '/' . $rIP . '/' . $rStreamID . '/' . $rInitSegment . '/' . $rUUID . '/' . SERVER_ID . '/' . $rVideoCodec . '/' . $rOnDemand, $rSettings['live_streaming_pass'], OPENSSL_EXTRA);
			}
			if ($rSettings['allow_cdn_access']) {
				$rSource = str_replace('URI="' . $rInitSegment . '"', 'URI="' . (($rProxyID ? '/' . md5($rProxyID . '_' . $rServerID . '_' . OPENSSL_EXTRA) : '')) . '/hls/' . $rInitSegment . '?token=' . $rInitToken . '"', $rSource);
			} else {
				$rSource = str_replace('URI="' . $rInitSegment . '"', 'URI="' . (($rProxyID ? '/' . md5($rProxyID . '_' . $rServerID . '_' . OPENSSL_EXTRA) : '')) . '/hls/' . $rInitToken . '"', $rSource);
			}
		}

		if (preg_match_all('/(.*?)\.(ts|m4s)/', $rSource, $rMatches)) {
			foreach ($rMatches[0] as $rMatch) {
				if ($rIsHMAC) {
					$rToken = Encryption::encrypt('HMAC#' . $rIsHMAC . '/' . $rIdentifier . '/' . $rIP . '/' . $rStreamID . '/' . $rMatch . '/' . $rUUID . '/' . SERVER_ID . '/' . $rVideoCodec . '/' . $rOnDemand, $rSettings['live_streaming_pass'], OPENSSL_EXTRA);
				} else {
					$rToken = Encryption::encrypt($rUsername . '/' . $rPassword . '/' . $rIP . '/' . $rStreamID . '/' . $rMatch . '/' . $rUUID . '/' . SERVER_ID . '/' . $rVideoCodec . '/' . $rOnDemand, $rSettings['live_streaming_pass'], OPENSSL_EXTRA);
				}
				if ($rSettings['allow_cdn_access']) {
					$rSource = str_replace($rMatch, (($rProxyID ? '/' . md5($rProxyID . '_' . $rServerID . '_' . OPENSSL_EXTRA) : '')) . '/hls/' . $rMatch . '?token=' . $rToken, $rSource);
				} else {
					$rSource = str_replace($rMatch, (($rProxyID ? '/' . md5($rProxyID . '_' . $rServerID . '_' . OPENSSL_EXTRA) : '')) . '/hls/' . $rToken, $rSource);
				}
			}
			return $rSource;
		}

		return false;
	}
}
