#! /bin/sh

set -ex

srcdir="$(dirname "$0")"
test -z "$srcdir" && srcdir=.

: "${AUTORECONF:=autoreconf}"
: "${AUTOMAKE:=automake}"

cd "$srcdir"

AUXFILES="config.guess config.sub install-sh"

clone_repo_commit() {
    if test -d "$2/.git"; then
        git -C "$2" reset --hard
        git -C "$2" clean -fd
        if ! git -C "$2" -c advice.detachedHead=false checkout $3; then
            rm -rf "$2"
        fi
    else
        if test -d "$2"; then
            set +x
            echo "error: '$2' is not a Git repository" 1>&2
            exit 1
        fi
    fi
    if ! test -d "$2"; then
        git clone $1 "$2"
        if ! git -C "$2" -c advice.detachedHead=false checkout $3; then
            rm -rf "$2"
            exit 1
        fi
    fi
}

download_by_hash() {
    DOWNLOAD_COMMAND="curl -Lo"
    if ! command -v "${DOWNLOAD_COMMAND%% *}" >/dev/null 2>&1; then
        DOWNLOAD_COMMAND="wget -O"
        if ! command -v "${DOWNLOAD_COMMAND%% *}" >/dev/null 2>&1; then
            set +x
            echo "error: Neither curl nor wget found" 1>&2
            exit 1
        fi
    fi
    SHA256_COMMAND="sha256sum"
    if ! command -v "${SHA256_COMMAND%% *}" >/dev/null 2>&1; then
        SHA256_COMMAND="sha256"
        if ! command -v "${SHA256_COMMAND%% *}" >/dev/null 2>&1; then
            set +x
            echo "error: Cannot find sha256(sum) command" 1>&2
            exit 1
        fi
    fi
    if ! test -f "$2" || ! $SHA256_COMMAND "$2" | grep $3 >/dev/null 2>&1; then
        rm -f "$2"
        mkdir -p "$2" && rm -rf "$2"
        $DOWNLOAD_COMMAND "$2" $1
        if ! $SHA256_COMMAND "$2" | grep $3 >/dev/null 2>&1; then
            set +x
            echo "error: Cannot download file '$2' by hash" 1>&2
            echo "incorrect hash:" 1>&2
            $SHA256_COMMAND "$2" 1>&2
            rm -f "$2"
            exit 1
        fi
    fi
}

if ! test -f version; then
    clone_repo_commit \
        https://codeberg.org/OSDev/freestnd-c-hdrs-0bsd.git \
        freestnd-c-hdrs \
        5e4e9e70278fe89ea328d359a58aff4f4a94b165

    clone_repo_commit \
        https://codeberg.org/OSDev/cc-runtime.git \
        cc-runtime \
        dae79833b57a01b9fd3e359ee31def69f5ae899b
    cp cc-runtime/src/cc-runtime.c common/cc-runtime.s2.c
    cp cc-runtime/src/cc-runtime.c decompressor/cc-runtime.c

    clone_repo_commit \
        https://codeberg.org/Limine/limine-protocol.git \
        limine-protocol \
        fedf97facd1c473ee8720f8dfd5a71d03490d928

    clone_repo_commit \
        https://codeberg.org/PicoEFI/PicoEFI.git \
        picoefi \
        4bd08c13f103de9efd7b215a3e337447f1e2ce37

    clone_repo_commit \
        https://github.com/jibsen/tinf.git \
        tinf \
        57ffa1f1d5e3dde19011b2127bd26d01689b694b
    mkdir -p decompressor/tinf
    cp tinf/src/tinf.h tinf/src/tinflate.c tinf/src/tinfgzip.c decompressor/tinf/
    patch -p0 < decompressor/tinf.patch
    rm -f decompressor/tinf/*.orig

    clone_repo_commit \
        https://codeberg.org/Mintsuki/Flanterm.git \
        flanterm \
        55d228ff16234513b0df0dd12de8bc58160fc196

    download_by_hash \
        https://github.com/nothings/stb/raw/5c205738c191bcb0abc65c4febfa9bd25ff35234/stb_image.h \
        common/lib/stb_image.h.nopatch \
        594c2fe35d49488b4382dbfaec8f98366defca819d916ac95becf3e75f4200b3
    cp common/lib/stb_image.h.nopatch common/lib/stb_image.h
    patch -p0 < common/stb_image.patch
    rm -f common/lib/stb_image.h.orig

    clone_repo_commit \
        https://codeberg.org/OSDev/libfdt.git \
        libfdt \
        7bf94e6347129d17eca263112296ad170dec28a9
fi

# Create timestamps file
if test -d .git && git log -1 >/dev/null 2>&1; then
    cat >timestamps <<EOF
REGEN_DATE="$(git log -1 --pretty=%cd --date='format:%B %Y')"
SOURCE_DATE_EPOCH="$(git log -1 --pretty=%ct)"
SOURCE_DATE_EPOCH_TOUCH="$(git log -1 --pretty=%cI | head -c 16 | sed 's/-//g;s/T//g;s/://g')"
EOF
else
    if ! test -f timestamps; then
        cat >timestamps <<EOF
REGEN_DATE="UNVERSIONED"
SOURCE_DATE_EPOCH="1546297200"
SOURCE_DATE_EPOCH_TOUCH="201901010000"
EOF
    fi
fi

for auxfile in $AUXFILES; do
    rm -f build-aux/$auxfile
done

$AUTORECONF -fvi -Wall

# Older versions of autoreconf have a bug where they do not
# install auxiliary files, sometimes... Check if that is the
# case and work around...
for auxfile in $AUXFILES; do
    if ! test -f build-aux/$auxfile; then
        if ! $AUTOMAKE --print-libdir >/dev/null 2>&1; then
            set +x
            echo "error: Broken autoreconf detected, but missing or broken automake." 1>&2
            echo "       Please make sure automake is installed and working." 1>&2
            exit 1
        fi
        AUTOMAKE_LIBDIR="$($AUTOMAKE --print-libdir)"
        if test -z "$AUTOMAKE_LIBDIR"; then
            # Assume `true` was passed as $AUTOMAKE
            continue
        fi
        mkdir -p build-aux
        cp -v "$AUTOMAKE_LIBDIR/$auxfile" build-aux/
        chmod +x build-aux/$auxfile
    fi
done

set +x

printf "\nSource tree bootstrapped successfully!\n"
