# vim:set ft=sh sw=4 sts=4 et:

SHORTNAME=quake2
LONGNAME="Quake II"

Q2MIRRORFILE=/etc/game-data-packager/quake2-mirrors
IDMIRRORFILE=/etc/game-data-packager/idstuff-mirrors

if [ "$0" = "./game-data-packager" ]; then
    Q2MIRRORFILE="./etc/quake2-mirrors"
    IDMIRRORFILE="./etc/idstuff-mirrors"
fi

demofile=q2-314-demo-x86.exe
demofilesha256=7ace5a43983f10d6bdc9d9b6e17a1032ba6223118d389bd170df89b945a04a1e
demodeb="quake2-demo-data"

patchfile=q2-3.20-x86-full-ctf.exe
patchfilesha256=f82197c8c8089202a4b3a85d8833b0c2e827a709d205c760369407c212488baa

fulldeb="quake2-full-data"

musicdeb="quake2-music"

quake2_usage() {
       printf "\
game-data-packager ${SHORTNAME} arguments:\n\
\n\
to make quake2-demo-data:\n\
game-data-packager ${SHORTNAME} [--demo] [<demo file>]\n\
\t<demo file>: path to ${demofile}\n\
\n\
to make quake2-full-data:\n\
game-data-packager ${SHORTNAME} [--full] [<full game>] [<patch>]\n\
\t<full game>: path to CD-ROM mount point or baseq2 directory\n\
\t<patch>: path to ${patchfile}\n\
\n\
to make quake2-music:\n\
game-data-packager ${SHORTNAME} [--music] [<device>]\n\
game-data-packager ${SHORTNAME} [--music] [<oggpath>]\n\
\t<device>: block device for Quake II CD-ROM, default is /dev/cdrom\n\
\t<oggpath>: directory containing [track]02*.ogg, ..., [track]11*.ogg\n\
\n\
to re-package installed data (full game or demo):\n\
game-data-packager ${SHORTNAME} --auto\n\
"
}

get_mirror () {
    (
        if [ -s "${Q2MIRRORFILE}" ]; then
            grep -v '^#' "${Q2MIRRORFILE}"
        fi
        grep -v '^#' "${IDMIRRORFILE}" | sed 's#$#/quake2#'
    ) | sort -R | head -n1
}

copyin () {
    install -d `dirname "$2"`
    install -m644 "$1" "$2"
}

go () {
    mode=help
    need_patchfile=
    need_demofile=
    retail_files_missing=
    cdpath=
    filepath=
    mirror=
    audiocd=/dev/cdrom
    oggs=
    # slipstream_instsize, slipstream_repack assume this naming
    DESTDIR="$WORKDIR/slipstream.unpacked"

    for arg in "$@"; do
        case "$arg" in
            (--auto)
                mode=auto
                ;;
            (--full)
                mode=full
                ;;
            (--demo)
                mode=demo
                ;;
            (--music)
                mode=music
                ;;
            (-*)
                quake2_usage
                die "unsupported option: $arg" 2
                ;;
            (*)
                if [ -d "$arg" ]; then
                    for candidate in "$arg/pak0.pak" \
                            "$arg/baseq2/pak0.pak" \
                            "$arg/install/data/baseq2/pak0.pak" \
                            "$arg/Install/Data/baseq2/pak0.pak" \
                            "$arg/setup/Data/baseq2/pak0.pak" \
                    ; do
                        if [ -f "$candidate" ]; then
                            echo "using $arg as the location of the full Quake II" \
                                "CD or installation"
                            cdpath="$arg"
                            mode=full
                        fi
                    done

                    if [ $mode = auto ] || [ $mode = music ]; then
                        if [ -f "$arg"/02*.ogg ]; then
                            echo "using $arg as the location of a" \
                                "Quake II soundtrack"
                            oggs="$arg"
                            mode=music
                            break
                        fi
                    fi

                    if [ $mode = auto ]; then
                        die "unable to work out what to do with directory $arg"
                    fi
                elif [ -f "$arg" ]; then
                    real=`sha256sum -b "$arg" | cut -d ' ' -f1`
                    case "$real" in
                        ($patchfilesha256)
                            echo "detected that $arg is the patch, will package the full game"
                            mode=full
                            ln -snf "`unravel "$arg"`" "$WORKDIR/$patchfile"
                            ;;
                        ($demofilesha256)
                            echo "detected that $arg is the demo, will package that"
                            mode=demo
                            ln -snf "`unravel "$arg"`" "$WORKDIR/$demofile"
                            ;;
                        (*)
                            die "$arg does not match the SHA256 of known Quake II files" 2
                            ;;
                    esac
                elif [ -b "$arg" ]; then
                    echo "using $arg as CD-ROM block device to rip music"
                    audiocd="$arg"
                    mode=music
                else
                    die "unable to work out what to do with $arg"
                fi
                ;;
        esac
    done

    if [ $mode = help ]; then
        quake2_usage
        exit 0
    fi

    debug "running in mode: $mode"

    if [ $mode != demo ] && [ $mode != music ]; then
        # Try to construct the full version. We process the files that
        # can only come from a full installation or retail CD first
        # (pak0.pak and the videos): if we can't find them, we must give up.

        # First look for them in /usr/share/games (repacking an existing
        # installation)
        while read line; do
            file="${line##*  }"
            exp="${line%% *}"

            debug "checking for /$file"

            if [ -f "/$file" ]; then
                debug "... found installed"
                real=`md5sum "/$file" | cut -d ' ' -f1`

                if [ "x$exp" = "x$real" ]; then
                    debug "... correct md5sum"
                    copyin "/$file" "$DESTDIR/$file"
                    continue
                else
                    warn "unexpected file contents:"
                    warn "    /$file"
                    warn "    expected: $exp"
                    warn "         got: $real"
                fi
            fi

            # OK, so we don't have the installed file. Look for it on the
            # CD or whatever
            if [ -n "$cdpath" ]; then
                inbaseq2="${file##usr/share/games/quake2/baseq2/}"
                found=""

                for candidate in "$cdpath/$inbaseq2" \
                        "$cdpath/baseq2/$inbaseq2" \
                        "$cdpath/install/data/baseq2/$inbaseq2" \
                        "$cdpath/Install/Data/baseq2/$inbaseq2" \
                        "$cdpath/setup/Data/baseq2/$inbaseq2" \
                ; do
                    debug "... trying $candidate"
                    if [ -f "$candidate" ]; then
                        debug "... found"
                        found="$candidate"
                        break
                    fi
                done

                if [ -n "$found" ]; then
                    real=`md5sum "$found" | cut -d ' ' -f1`

                    if [ "x$exp" = "x$real" ]; then
                        debug "... correct md5sum"
                        copyin "$found" "$DESTDIR/$file"
                        continue
                    else
                        warn "unexpected file contents:"
                        warn "    $found"
                        warn "    expected: $exp"
                        warn "         got: $real"
                    fi
                fi
            fi

            # OK, I give up.
            retail_files_missing=1
        done < "$DATADIR/quake2/cd.md5sums"
    fi

    if [ -n "${retail_files_missing}" ]; then
        case $mode in
            (auto)
                debug "some retail file was missing, doing the demo instead"
                mode=demo
                ;;
            (full)
                die "could not find required files for quake2-full-data" 1
                ;;
        esac
    elif [ $mode = auto ]; then
        debug "looks like we have the full version of Quake II"
        mode=full
    fi

    if [ ${mode} = full ]; then
        deb="$fulldeb"
        debug "continuing to package full Quake II"

        if [ -e /usr/share/games/quake2/baseq2/pak1.pak ]; then
            # Try to reconstitute the patch from installed files. If we can do
            # that, we won't have to download it.
            echo "found Quake II data in /usr/share/games/quake2..."
            while read line; do
                file="${line##*  }"
                exp="${line%% *}"

                if ! [ -f "/$file" ]; then
                    warn "required file not found:"
                    warn "    /$file"
                    warn "will download the patch instead"
                    need_patchfile=1
                    break
                fi

                real=`md5sum "/$file" | cut -d ' ' -f1`

                if [ "x$exp" = "x$real" ]; then
                    copyin "/$file" "$DESTDIR/$file"
                else
                    warn "unexpected file contents:"
                    warn "    /$file"
                    warn "    expected: $exp"
                    warn "         got: $real"
                    warn "will download the patch instead"
                    need_patchfile=1
                    break
                fi
            done < "$DATADIR/quake2/patch.md5sums"
        else
            need_patchfile=1
        fi

        if [ -n "${need_patchfile}" ]; then
            if ! [ -e "$WORKDIR/$patchfile" ]; then
                echo "downloading $patchfile..."
                [ -n "$mirror" ] || mirror=`get_mirror`
                wget -O "$WORKDIR/$patchfile" "$mirror/$patchfile"
            fi

            exp=$patchfilesha256
            real=`sha256sum -b "$WORKDIR/$patchfile" | cut -d ' ' -f1`

            if [ "x$real" != "x$exp" ]; then
                warn "$patchfile sha256sum does not match expected value"
                [ -z "$mirror" ] || warn "downloaded: $mirror/$demofile"
                warn "expected: $exp"
                warn "     got: $real"
                die "please obtain a correct copy of $patchfile" 1
            fi

            while read line; do
                file="${line##*  }"

                case "$file" in
                    (usr/share/games/quake2/baseq2/*|usr/share/games/quake2/ctf/*)
                        src="${file#usr/share/games/quake2/}"
                        ;;
                    (usr/share/doc/quake2-full-data/*)
                        src="DOCS/${file#usr/share/doc/quake2-full-data/}"
                        ;;
                    (*)
                        die "internal error: unexpected path $file found in patch.md5sums"
                        exit 1
                        ;;
                esac

                debug "extracting $src"
                gdp_unzip_paths "$WORKDIR/$patchfile" "$WORKDIR" "$src"
                exp="${line%% *}"
                real=`md5sum "$WORKDIR/$src" | cut -d ' ' -f1`

                if [ "x$real" != "x$exp" ]; then
                    # we checked the patch file's SHA256, so this shouldn't
                    # ever happen...
                    warn "$file md5sum from $patchfile does not match expected value"
                    warn "expected: $exp"
                    warn "     got: $real"
                    die "this shouldn't have happened"
                fi
                copyin "$WORKDIR/$src" "$DESTDIR/$file"
            done < "$DATADIR/quake2/patch.md5sums"
        fi
    elif [ ${mode} = demo ]; then
        deb="$demodeb"

        if [ -e /usr/share/games/quake2-demo/baseq2/pak0.pak ]; then
            # Try to reconstitute the demo from installed files. If we can do
            # that, we won't have to download it.
            echo "found demo data in /usr/share/games/quake2-demo..."
            while read line; do
                file="${line##*  }"
                exp="${line%% *}"

                if ! [ -f "/$file" ]; then
                    warn "required file not found:"
                    warn "    /$file"
                    warn "will unpack ${demofile} instead"
                    need_demofile=1
                    break
                fi

                real=`md5sum "/$file" | cut -d ' ' -f1`

                if [ "x$exp" = "x$real" ]; then
                    copyin "/$file" "$DESTDIR/$file"
                else
                    warn "unexpected file contents:"
                    warn "    /$file"
                    warn "    expected: $exp"
                    warn "         got: $real"
                    warn "will download the demo instead"
                    need_demofile=1
                    break
                fi
            done < "$DATADIR/quake2/demo.md5sums"
        else
            need_demofile=1
        fi

        if [ -n "${need_demofile}" ]; then
            if ! [ -e "$WORKDIR/$demofile" ]; then
                echo "downloading $demofile..."
                [ -n "$mirror" ] || mirror=`get_mirror`
                wget -O "$WORKDIR/$demofile" "$mirror/$demofile"
            fi

            exp=$demofilesha256
            real=`sha256sum -b "$WORKDIR/$demofile" | cut -d ' ' -f1`

            if [ "x$real" != "x$exp" ]; then
                warn "$demofile sha256sum does not match expected value"
                [ -z "$mirror" ] || warn "downloaded: $mirror/$demofile"
                warn "expected: $exp"
                warn "     got: $real"
                die "please obtain a correct copy of $demofile" 1
            fi

            while read line; do
                file="${line##*  }"

                case "$file" in
                    (usr/share/games/quake2-demo/baseq2/*)
                        src="Install/Data/${file#usr/share/games/quake2-demo/}"
                        ;;
                    (usr/share/doc/quake2-demo-data/*)
                        src="Install/Data/DOCS/${file#usr/share/doc/quake2-demo-data/}"
                        ;;
                    (*)
                        die "internal error: unexpected path $file found in demo.md5sums"
                        ;;
                esac

                debug "extracting $src"
                gdp_unzip_paths "$WORKDIR/$demofile" "$WORKDIR" "$src"
                exp="${line%% *}"
                real=`md5sum "$WORKDIR/$src" | cut -d ' ' -f1`

                if [ "x$real" != "x$exp" ]; then
                    # we checked the patch file's SHA256, so this shouldn't
                    # ever happen...
                    warn "$file md5sum from $demofile does not match expected value"
                    warn "expected: $exp"
                    warn "     got: $real"
                    die "this shouldn't happen"
                fi
                copyin "$WORKDIR/$src" "$DESTDIR/$file"
            done < "$DATADIR/quake2/demo.md5sums"
        fi
    elif [ $mode = music ]; then
        deb="$musicdeb"

        install -d "$DESTDIR/usr/share/games/quake2/baseq2/music"

        if [ -n "$oggs" ]; then
            t=02
            while [ -f "$oggs/$t"*.ogg ]; do
                copyin "$oggs/$t"*.ogg \
                    "$DESTDIR/usr/share/games/quake2/baseq2/music/${t}.ogg"
                t=$(( ${t#0} + 1 ))
                if [ $t -lt 10 ]; then
                    t=0$t
                fi
            done
        else
            packages="cdparanoia vorbis-tools"
            require_program "cdparanoia" $packages
            require_program "oggenc" $packages

            t=02
            while cdparanoia -d "$audiocd" $t "${WORKDIR}/tmp.wav"; do
                oggenc -o "$DESTDIR/usr/share/games/quake2/baseq2/music/${t}.ogg" "${WORKDIR}/tmp.wav"
                rm -f "${WORKDIR}/tmp.wav"
                t=$(( ${t#0} + 1 ))
                if [ $t -lt 10 ]; then
                    t=0$t
                fi
            done
        fi
    else
        die "internal error: impossible mode $mode" 1
    fi

    if [ "" = "$OUTDIR" ]; then
        OUTFILE="$WORKDIR/out.deb"
    else
        OUTFILE=`unravel "$OUTDIR"`"/${deb}_${GAME_PACKAGE_VERSION}_all.deb"
    fi

    copyin "$DATADIR/changelog.gz" \
        "$DESTDIR/usr/share/doc/$deb/changelog.gz"
    copyin "$DATADIR/quake2/${deb}.copyright" \
        "$DESTDIR/usr/share/doc/${deb}/copyright"

    # slipstream_instsize, slipstream_repack assume that slipstream.unpacked
    # and DEBIAN are in the same place
    copyin "$DATADIR/quake2/${deb}.control" \
        "$WORKDIR/DEBIAN/control"
    copyin "$DATADIR/quake2/${deb}.md5sums" \
        "$WORKDIR/DEBIAN/md5sums"

    if [ $mode = music ]; then
        # we still need to md5sum the actual tracks - their contents
        # depend on the user's copy of oggenc
        ( cd "$DESTDIR" && md5sum usr/share/games/quake2/baseq2/music/*.ogg \
            >> ../DEBIAN/md5sums )
    else
        # sanity check
        ( cd "$DESTDIR" && md5sum --check --quiet ../DEBIAN/md5sums )
    fi

    debug "building .deb: $OUTFILE"
    ( cd "$WORKDIR" && slipstream_instsize )
    ( cd "$WORKDIR" && slipstream_repack "$OUTFILE" )

    rm -fr "$WORKDIR/$demofile"
    rm -fr "$WORKDIR/$patchfile"
    rm -fr "$WORKDIR/baseq2"
    rm -fr "$WORKDIR/ctf"
    rm -fr "$WORKDIR/DOCS"
    rm -fr "$WORKDIR/Install"
    rm -fr "$WORKDIR/repack"
    rm -fr "$DESTDIR"
}
