#!/bin/bash

# script/build: Build the Trezor firmware in a clean working tree.
#

# this needs to be there, otherwise python click installer vomits an error
export LC_ALL=C.UTF-8
export LANG=C.UTF-8

set -eu

cd "$(dirname "$0")/../.."

EMULATOR=${EMULATOR:-0}

readonly MCU_ROOT=legacy

readonly ARTIFACT_EXTENSIONS=(bin elf)
readonly BUILD_DIR="$(readlink -f build)"

readonly BOOTLOADER_DIR="$BUILD_DIR/legacy/bootloader"
readonly BOOTLOADER_FILENAME="$MCU_ROOT/bootloader/bootloader.bin"
readonly BOOTLOADER_PATH="$BOOTLOADER_DIR/$BOOTLOADER_FILENAME"

readonly FIRMWARE_DIR="$BUILD_DIR/legacy/firmware"
readonly FIRMWARE_FILENAME="$MCU_ROOT/firmware/trezor.bin"
readonly FIRMWARE_PATH="$FIRMWARE_DIR/$FIRMWARE_FILENAME"

readonly EMULATOR_DIR="$FIRMWARE_DIR"
readonly EMULATOR_FILENAME="$MCU_ROOT/firmware/trezor-emulator.elf"
readonly EMULATOR_PATH="$EMULATOR_DIR/$MCU_ROOT/firmware/trezor.elf"

worktree_setup() {
    local path="$1"
    local commit="$2"

    rm -rf "$path"
    git clone -n --reference=. . "$path" --recurse-submodules

    # Use `git rev-parse` so that we can use any reference from the working repository.
    git -C "$path" checkout "$(git rev-parse "$commit")"

    ( cd "$path/$MCU_ROOT" && script/setup )
}

worktree_build() {
    local path="$1"

    if [ ! -e "$path/Pipfile" ]; then
        echo "Can't handle pre-monorepo tags properly. You will have to check out manually"
        exit 1
    fi

    pushd $path
    export HOME=/tmp
    pipenv install
    pipenv run $MCU_ROOT/script/cibuild
    popd
}

worktree_copy() {
    local path="$1"
    local filename="$2"
    local pattern="$3"

    local describe="$(git -C "$path" describe --tags --match "legacy/$pattern")"
    describe="${describe##legacy/}"

    local src="$path/$filename"

    local basename="$(basename "$filename")"
    local dest="$BUILD_DIR/${basename%.*}-$describe.${basename##*.}"

    if [ "$EMULATOR" = 1 ]; then
        install -Dm0644 "${src%.*}.elf" "${dest%.*}.elf"
    else
        for extension in "${ARTIFACT_EXTENSIONS[@]}"; do
            install -Dm0644 \
                "${src%.*}.$extension" \
                "${dest%.*}.$extension"
        done
    fi

    printf "%s" "$dest"
}

main() {
    local bootloader_commit="$1"
    local firmware_commit="$2"

    worktree_setup "$FIRMWARE_DIR" "$firmware_commit"

    if [ "$EMULATOR" != 1 ]; then
        worktree_setup "$BOOTLOADER_DIR" "$bootloader_commit"
        worktree_build "$BOOTLOADER_DIR"

        cp "$BOOTLOADER_PATH" "$FIRMWARE_DIR/$BOOTLOADER_FILENAME"
    fi

    worktree_build "$FIRMWARE_DIR"

    if [ "$EMULATOR" = 1 ]; then
        cp "$EMULATOR_PATH" "$EMULATOR_DIR/$EMULATOR_FILENAME"
        local firmware_path="$(worktree_copy \
            "$EMULATOR_DIR" \
            "$EMULATOR_FILENAME" \
            "v*")"
        chmod +x "$firmware_path"

    else

        local firmware_path="$(worktree_copy \
            "$FIRMWARE_DIR" \
            "$FIRMWARE_FILENAME" \
            "v*")"

        local bootloader_path="$(worktree_copy \
            "$BOOTLOADER_DIR" \
            "$BOOTLOADER_FILENAME" \
            "bl*")"

        printf "\n\n"; $PYTHON $MCU_ROOT/script/fingerprint \
            "$bootloader_path" \
            --max-size 32768 \
            --double
    fi

    printf "\n\n"; $PYTHON $MCU_ROOT/script/fingerprint \
        "$firmware_path" \
        --offset 256 \
        --max-size 983296  # 256 + 64*1024 + 3*128*1024 + 4*128*1024
}

main "$@"