<?php
ini_set('display_errors', '1');
ini_set('display_startup_errors', '1');
error_reporting(E_ALL);

function fetch_url_with_curl($url, $host_override = '', $ip_override = '') {
    if(!function_exists('curl_init')) {
        return ['content' => false, 'http_code' => 0, 'error' => 'curl 확장 없음'];
    }

    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
    curl_setopt($ch, CURLOPT_TIMEOUT, 10);
    curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);

    $headers = [];
    if($host_override) $headers[] = "Host: $host_override";
    if($headers) curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

    if($ip_override) {
        $scheme = parse_url($url, PHP_URL_SCHEME) ?: 'http';
        $port = ($scheme === 'https') ? 443 : 80;
        curl_setopt($ch, CURLOPT_RESOLVE, ["$host_override:$port:$ip_override"]);
    }

    $content = curl_exec($ch);
    $err = curl_error($ch);
    $info = curl_getinfo($ch);
    curl_close($ch);

    // 안정성: 실패했으면 강제로 http_code=0 처리
    if($err || !$content) {
        $info['http_code'] = 0;
    }

    return ['content' => $content, 'http_code' => $info['http_code'] ?? 0, 'error' => $err ?: null];
}

function fetch_url_fallback($url) {
    $ctx = stream_context_create(['http'=>['timeout'=>10]]);
    $content = @file_get_contents($url, false, $ctx);
    $http_code = ($content !== false) ? 200 : 0;
    return ['content' => $content, 'http_code' => $http_code, 'error' => null];
}

$results = [];

if(isset($_POST['playlist_url'])){
    $playlist_url = trim($_POST['playlist_url']);
    $ip_text = isset($_POST['ip_override']) ? trim($_POST['ip_override']) : '';

    $ip_list = [];
    if($ip_text === '') $ip_list[] = '';
    else {
        foreach(preg_split('/[\r\n,;]+/', $ip_text) as $l) {
            $v = trim($l);
            if($v !== '') $ip_list[] = $v;
        }
    }

    if(empty($ip_list)) $ip_list[] = '';

    $parsed = @parse_url($playlist_url);
    if(!$parsed || !isset($parsed['host'])) {
        $results[] = ['ip'=>'(invalid)','error'=>'URL 오류'];
    } else {
        $host = $parsed['host'];
        $scheme = $parsed['scheme'] ?? 'https';
        $path = $parsed['path'] ?? '/';
        $base_path = rtrim(substr($path, 0, strrpos($path, '/') ?: 0), '/') ?: '';

        foreach($ip_list as $ip_override) {
            $res = ['ip'=>$ip_override ?: '(default DNS)', 'playlist'=>null, 'chunklist'=>null, 'll_hls'=>null];

            // playlist
            $p = fetch_url_with_curl($playlist_url, $host, $ip_override ?: '');
            $res['playlist'] = $p;
            if(!$p['content']) { $results[]=$res; continue; }

            // chunklist
            preg_match_all('/^[^#].*$/m', $p['content'], $matches);
            $chunklist_rel = null;
            foreach($matches[0] as $l) {
                if(stripos($l,'.m3u8')!==false) { $chunklist_rel=$l; break; }
            }
            if(!$chunklist_rel){ $results[]=$res; continue; }

            $chunklist_url = (strpos($chunklist_rel,'http')===0)
                ? $chunklist_rel
                : $scheme.'://'.$host.($base_path?'/'.$base_path.'/':'/').$chunklist_rel;

            $c = fetch_url_with_curl($chunklist_url, $host, $ip_override ?: '');
            $res['chunklist'] = $c;
            if(!$c['content']) { $results[]=$res; continue; }

            // LL-HLS 체크
            if(preg_match('/LAST-MSN\s*=\s*(\d+)/i',$c['content'],$m)){
                $last=$m[1];
                $ll_url=$chunklist_url."?_HLS_msn=$last&_HLS_part=1";
                $ll=fetch_url_with_curl($ll_url,$host,$ip_override?:'');
                $res['ll_hls']=$ll;
            }

            $results[]=$res;
        }
    }
}
?>
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>m3u8 Crawler</title>
<style>
body{font-family:system-ui,Arial;padding:16px}
table{border-collapse:collapse;width:100%;margin-top:12px}
th,td{border:1px solid #ccc;padding:8px;text-align:left}
.status-ok{color:green;font-weight:bold}
.status-bad{color:red;font-weight:bold}
textarea{width:100%;height:120px}
</style>
</head>
<body>
<h2>m3u8 Crawler - HTTP 200 완전 검증</h2>
<form method="post">
  playlist.m3u8 URL:<br>
  <input type="text" name="playlist_url" size="80" value="<?php echo isset($_POST['playlist_url'])?htmlspecialchars($_POST['playlist_url']):''; ?>"><br><br>
  IP 리스트 (비우면 기본 DNS):<br>
  <textarea name="ip_override"><?php echo isset($_POST['ip_override'])?htmlspecialchars($_POST['ip_override']):''; ?></textarea><br>
  <button type="submit">실행</button>
</form>

<?php if(!empty($results)): ?>
<table>
<thead><tr><th>IP</th><th>Playlist</th><th>Chunklist</th><th>LL-HLS</th><th>이상 유무</th></tr></thead>
<tbody>
<?php foreach($results as $r):
    $p = $r['playlist']['http_code'] ?? 0;
    $c = $r['chunklist']['http_code'] ?? 0;
    $l = $r['ll_hls']['http_code'] ?? 0;
    $codes = array_filter([$p,$c,$l]);
    $is_ok = (!empty($codes) && count(array_filter($codes,fn($x)=>$x==200))===count($codes));
?>
<tr>
  <td><?php echo htmlspecialchars($r['ip']); ?></td>
  <td><?php echo $p ?: '-'; ?></td>
  <td><?php echo $c ?: '-'; ?></td>
  <td><?php echo $l ?: '-'; ?></td>
  <td><?php echo $is_ok ? '<span class="status-ok">O</span>' : '<span class="status-bad">X</span>'; ?></td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
<?php endif; ?>
</body>
</html>

