#!/bin/sh
#
#  check-vlckit-licences.sh
#  Popvue
#
#  Fails when the MobileVLCKit binary carries code under the GPL rather than the LGPL, by the
#  names of the code known to be: zvbi, the one library VLCKit can bundle with GPL 2 only parts
#  (its teletext packet 8/30 decoder); the libVLC modules whose sources are GPL 2 or later --
#  the seven that build-vlckit.sh's patches leave out, and the twenty VideoLAN's own build
#  already does; and the GPL code inside LGPL modules, yadif in deinterlace and the motion
#  library rotate links. Popvue's VLCKit is built without all of it (build-vlckit.sh); this
#  keeps it that way through any future rebuild or update. A module this list does not name is
#  caught where the build is made, by find-gpl-sources.py. Run by build-vlckit.sh, and by the
#  app's build ("Check VLCKit licences") against the framework it embeds.
#
#  Usage: check-vlckit-licences.sh <MobileVLCKit.xcframework or a MobileVLCKit binary>
#

set -e

# libVLC's GPL modules, by their entry points (_vlc_entry__<folder>_<module>, the full names
# VLCKit's build gives its modules): every one libVLC 3.0's iOS build compiles.
GPL_MODULES="
access_rtsp_libaccess_realrtsp
audio_filter_channel_mixer_dolby
audio_filter_channel_mixer_headphone
audio_filter_channel_mixer_mono
codec_t140
control_dummy
control_gestures
control_hotkeys
control_motion
control_netsync
control_oldrc
demux_real
logger_file
logger_syslog
misc_audioscrobbler
misc_logger
misc_playlist_export
misc_rtsp
misc_stats
services_discovery_libsap
services_discovery_mediadirs
services_discovery_podcast
spu_libremoteosd
stream_out_libstream_out_rtp
video_filter_hqdn3d
video_filter_rotate
visualization_visual_visual
"

TARGET="$1"
if [ -z "$TARGET" ] || [ ! -e "$TARGET" ]; then
    echo "error: check-vlckit-licences.sh: no MobileVLCKit at '$TARGET'" >&2
    exit 1
fi

if [ -d "$TARGET" ]; then
    BINARIES=$(find "$TARGET" -type f -name MobileVLCKit -path "*MobileVLCKit.framework/*")
else
    BINARIES="$TARGET"
fi

if [ -z "$BINARIES" ]; then
    echo "error: check-vlckit-licences.sh: no MobileVLCKit binary inside '$TARGET'" >&2
    exit 1
fi

STATUS=0
# One path a line, so a folder with spaces in its name (a build directory) stays one path.
IFS='
'
for BINARY in $BINARIES; do
    # Read once each. A tool that could not read the binary would find no GPL code either, so
    # each must also find libVLC itself -- its entry point, its name, and HTTP's module among the
    # local symbols the modules' entry points are -- before its silence counts. A framework
    # stripped of its local symbols is one this check cannot read.
    SYMBOLS=$(nm -gU "$BINARY" 2>/dev/null | grep -E " _(vbi_|libvlc_new$)" || true)
    LOCALS=$(nm -U "$BINARY" 2>/dev/null | grep -E " _(vlc_entry__[A-Za-z0-9_]+|RenderYadif|RenderYadifSingle|yadif_filter_line_c|motion_create|motion_get_angle)$" || true)
    TEXTS=$(strings -a "$BINARY" 2>/dev/null | grep -E -o "packet-830\.c|libzvbi|LibVLC/[0-9]" | sort -u || true)
    if ! printf '%s\n' "$SYMBOLS" | grep -q " _libvlc_new$" \
        || ! printf '%s\n' "$LOCALS" | grep -q " _vlc_entry__access_http$" \
        || ! printf '%s\n' "$TEXTS" | grep -q "LibVLC/"; then
        echo "error: check-vlckit-licences.sh: could not read libVLC's symbols and strings in $BINARY" >&2
        STATUS=1
        continue
    fi
    FOUND=""
    # zvbi's public functions all start vbi_ (its packet 8/30 decoder is vbi_decode_teletext_8301*);
    # no other library VLCKit bundles uses that prefix. zvbi linked without exporting its symbols
    # still leaves its own strings behind.
    if printf '%s\n' "$SYMBOLS" | grep -q " _vbi_" || printf '%s\n' "$TEXTS" | grep -q -E "packet-830|libzvbi"; then
        FOUND="$FOUND zvbi"
    fi
    for MODULE in $GPL_MODULES; do
        if printf '%s\n' "$LOCALS" | grep -q " _vlc_entry__$MODULE$"; then
            FOUND="$FOUND $MODULE"
        fi
    done
    if printf '%s\n' "$LOCALS" | grep -q -E " _(RenderYadif|RenderYadifSingle|yadif_filter_line_c)$"; then
        FOUND="$FOUND deinterlace's yadif"
    fi
    if printf '%s\n' "$LOCALS" | grep -q -E " _motion_(create|get_angle)$"; then
        FOUND="$FOUND motionlib"
    fi
    if [ -n "$FOUND" ]; then
        echo "error: MobileVLCKit includes GPL code:$FOUND: $BINARY" >&2
        echo "error: rebuild it with Scripts/vlckit/build-vlckit.sh (see Vendor/MobileVLCKit/README.md)" >&2
        STATUS=1
    fi
done

if [ "$STATUS" -eq 0 ]; then
    echo "check-vlckit-licences: no zvbi and no GPL libVLC code in MobileVLCKit"
fi
exit $STATUS
