#!/bin/bash
set -euo pipefail

INPUT="$1"
BASENAME=$(basename "$INPUT" | sed 's/\.[^.]*$//')
OUTDIR_NAME="${BASENAME}-Transcode"
mkdir -p "$OUTDIR_NAME/sub-titles" "$OUTDIR_NAME/video/1080p" "$OUTDIR_NAME/video/720p" "$OUTDIR_NAME/audio"
OUTDIR=$(realpath "$OUTDIR_NAME")

# 0️⃣ Analyze Input
echo "analyzing input and creating mediainfo.json"
ffprobe -v quiet -print_format json -show_format -show_streams "$INPUT" > "$OUTDIR/mediainfo.json"

FPS=$(ffprobe -v 0 -select_streams v:0 -show_entries stream=r_frame_rate -of default=noprint_wrappers=1:nokey=1 "$INPUT" | bc -l)
GOP=$(printf "%.0f" $(echo "$FPS * 6" | bc -l))

# 1️⃣ Master Playlist
MASTER="$OUTDIR/playlist.m3u8"
printf "#EXTM3U\n#EXT-X-VERSION:6\n#EXT-X-INDEPENDENT-SEGMENTS\n\n" > "$MASTER"

# Subtitles Group
SUB_DATA=$(jq -r '.streams[] | select(.codec_type=="subtitle") | select(.codec_name | test("subrip|ass|webvtt|mov_text")) | @base64' "$OUTDIR/mediainfo.json")
s_count=0
for s in $SUB_DATA; do
    _jq() { echo "$s" | base64 --decode | jq -r "$1"; }
    S_IDX=$(_jq '.index')
    S_LANG=$(_jq '.tags.language // "und"')
    printf "#EXT-X-MEDIA:TYPE=SUBTITLES,GROUP-ID=\"subs\",NAME=\"%s\",LANGUAGE=\"%s\",AUTOSELECT=YES,DEFAULT=%s,URI=\"sub-titles/%s_%s/stream.m3u8\"\n" \
        "${S_LANG^^}_$S_IDX" "$S_LANG" "$([ $s_count -eq 0 ] && echo "YES" || echo "NO")" "$S_IDX" "$S_LANG" >> "$MASTER"
    s_count=$((s_count+1))
done

# Audio Group
AUDIO_DATA=$(jq -r '.streams[] | select(.codec_type=="audio") | @base64' "$OUTDIR/mediainfo.json")
a_count=0
for s in $AUDIO_DATA; do
    _jq() { echo "$s" | base64 --decode | jq -r "$1"; }
    A_IDX=$(_jq '.index')
    A_LANG=$(_jq '.tags.language // "und"')
    A_TITLE=$(_jq '.tags.title // "Audio"')
    A_ROLE=$(_jq '.tags.role // ""')
    
    CHARS=""
    if [[ "$A_ROLE" == *"main-desc"* ]] || [[ "$A_TITLE" == *"Description"* ]] || [[ "$A_TITLE" == *"AD"* ]]; then
        CHARS=",CHARACTERISTICS=\"public.accessibility.describes-video\""
    fi

    printf "#EXT-X-MEDIA:TYPE=AUDIO,GROUP-ID=\"audio\",NAME=\"%s\",LANGUAGE=\"%s\",AUTOSELECT=YES,DEFAULT=%s%s,URI=\"audio/%s_%s/stream.m3u8\"\n" \
        "$A_TITLE" "$A_LANG" "$([ $a_count -eq 0 ] && echo "YES" || echo "NO")" "$CHARS" "$A_IDX" "$A_LANG" >> "$MASTER"
    a_count=$((a_count+1))
done

# Video Variants
printf "#EXT-X-STREAM-INF:BANDWIDTH=6000000,RESOLUTION=1920x1080,CODECS=\"avc1.64002a,mp4a.40.2\",AUDIO=\"audio\",SUBTITLES=\"subs\"\nvideo/1080p/stream.m3u8\n" >> "$MASTER"
printf "#EXT-X-STREAM-INF:BANDWIDTH=3000000,RESOLUTION=1280x720,CODECS=\"avc1.64002a,mp4a.40.2\",AUDIO=\"audio\",SUBTITLES=\"subs\"\nvideo/720p/stream.m3u8\n" >> "$MASTER"

# 2️⃣ Extract Subtitles (Fixing the Muxer Error)
echo "extracting subtitles"
for s in $SUB_DATA; do
    _jq() { echo "$s" | base64 --decode | jq -r "$1"; }
    S_IDX=$(_jq '.index')
    S_LANG=$(_jq '.tags.language // "und"')
    S_DIR="$OUTDIR/sub-titles/${S_IDX}_${S_LANG}"
    mkdir -p "$S_DIR"

    # Use the 'segment' muxer instead of 'hls' muxer for VTT. 
    # This avoids the MPEG-TS conflict entirely.
    ffmpeg -y -i "$INPUT" -map 0:"$S_IDX" \
        -c:s webvtt -f segment -segment_time 6 -segment_list "$S_DIR/stream.m3u8" \
        -segment_list_type m3u8 -segment_format webvtt \
        "$S_DIR/s_%d.vtt" -loglevel error

    # Post-process the playlist to add the required HLS headers that 'segment' muxer omits
    sed -i '1i #EXTM3U\n#EXT-X-VERSION:3\n#EXT-X-TARGETDURATION:6\n#EXT-X-PLAYLIST-TYPE:VOD' "$S_DIR/stream.m3u8"
    echo "#EXT-X-ENDLIST" >> "$S_DIR/stream.m3u8"
done

# 3️⃣ Process Video (NVENC)
echo "transcoding 1080p h264 video using nvenc"
ffmpeg -y -hwaccel cuda -i "$INPUT" -map 0:v:0 -c:v h264_nvenc -b:v 6000k -g "$GOP" -keyint_min "$GOP" -sc_threshold 0 \
    -vf "scale=1920:1080" -f hls -hls_time 6 -hls_playlist_type vod -hls_segment_type fmp4 \
    -hls_segment_filename "$OUTDIR/video/1080p/v_%d.m4s" -hls_fmp4_init_filename "init.mp4" "$OUTDIR/video/1080p/stream.m3u8" -loglevel error

echo "transcoding 720p h264 video using nvenc"
ffmpeg -y -hwaccel cuda -i "$INPUT" -map 0:v:0 -c:v h264_nvenc -b:v 3000k -g "$GOP" -keyint_min "$GOP" -sc_threshold 0 \
    -vf "scale=1280:720" -f hls -hls_time 6 -hls_playlist_type vod -hls_segment_type fmp4 \
    -hls_segment_filename "$OUTDIR/video/720p/v_%d.m4s" -hls_fmp4_init_filename "init.mp4" "$OUTDIR/video/720p/stream.m3u8" -loglevel error

# 4️⃣ Process Audio
echo "transcoding audio streams"
for s in $AUDIO_DATA; do
    _jq() { echo "$s" | base64 --decode | jq -r "$1"; }
    A_IDX=$(_jq '.index')
    A_LANG=$(_jq '.tags.language // "und"')
    A_DIR="$OUTDIR/audio/${A_IDX}_${A_LANG}"
    mkdir -p "$A_DIR"
    
    ffmpeg -y -i "$INPUT" -map 0:"$A_IDX" -c:a aac -b:a 160k -f hls -hls_time 6 -hls_playlist_type vod -hls_segment_type fmp4 \
        -hls_segment_filename "$A_DIR/a_%d.m4s" -hls_fmp4_init_filename "init.mp4" "$A_DIR/stream.m3u8" -loglevel error
done

echo "Success! Structure: $OUTDIR"
