#!/bin/sh

set -e

die() {
    echo "$@" >&2
    exit 1
}

dbus_do() {
    local dest="$1"
    shift

    dbus-send --system --print-reply --dest="$dest" "$@"
}

ofono_dbus() {
    dbus_do "org.ofono" "$@"
}

ofa_dbus() {
    dbus_do "org.freedesktop.Accounts" "$@"
}

# stdin: DBus reply, stdout: DBus object paths, one per line
dbus_object_paths() {
    sed -n 's/^ *object path "\(.*\)"$/\1/p'
}

# DBus object paths of oFono modems, one per line; bails out if oFono isn't
# available
get_modems() {
    local modems

    if ! modems="$(ofono_dbus / org.ofono.Manager.GetModems)"; then
        return 1
    fi
    # convert to /ril_0 etc. object paths
    echo "$modems" | dbus_object_paths
}

# extracts value of a property from a DBus reply; variant is the type
# e.g. string or boolean
get_dbus_prop() {
    local data="$1"
    local variant="$2"
    local name="$3"

    echo "$data" |
        grep -A1 "^ *string \"$name\"$" |
        sed -n "s/^ *variant \\+$variant //p"
}

# extracts value of a string property from a DBus reply
get_string() {
    local data="$1"
    local name="$2"

    get_dbus_prop "$data" "string" "$name" | sed 's/^"\(.*\)"$/\1/'
}

setup_here_device_id() {
    local data

    if ! data="$(dbus_do com.ubuntu.WhoopsiePreferences /com/ubuntu/WhoopsiePreferences com.ubuntu.WhoopsiePreferences.GetIdentifier)"; then
        die "Couldn't get Whoopsie identifier"
    fi
    HERE_UNIQUE_DEVICE_ID="$(echo "$data" | sed -n 's/^ *string "\(.*\)"$/\1/p')"
    export HERE_UNIQUE_DEVICE_ID
}

# sets HERE env vars which depend only on properties
# TODO set sensible values for systems without getprop
setup_here_props() {
    HERE_DEVICE_TERMINAL_MODEL="$(getprop ro.product.model)"
    HERE_DEVICE_MANUFACTURER="$(getprop ro.product.manufacturer)"
    HERE_DEVICE_FIRMWARE_VERSION="$(getprop ro.build.version.incremental)"
    export HERE_DEVICE_TERMINAL_MODEL HERE_DEVICE_MANUFACTURER HERE_DEVICE_FIRMWARE_VERSION
}

# sets HERE env vars which depend on oFono and a modem + SIM being ready
setup_here_ofono_env() {
    local modems
    local modem
    local data
    local serial

    if ! modems="$(get_modems)"; then
        die "Couldn't get modems from oFono"
    fi

    if [ -z "$modems" ]; then
        die "No modem found"
    fi

    for modem in "$modems"; do
        # get properties of this modem
        if ! data="$(ofono_dbus "$modem" org.ofono.Modem.GetProperties)"; then
            echo "Couldn't get properties of modem $modem; skipping" >&2
            continue
        fi
        # extract Serial
        if ! serial=$(get_string "$data" "Serial"); then
            echo "Couldn't get Serial for modem $modem; skipping" >&2
            continue
        fi
        HERE_IMEI_FRAGMENT="$(echo "$serial" | grep -o '[0-9]*' | cut -c 1-8)"
        export HERE_IMEI_FRAGMENT

        # get properties of this SIM
        if ! data="$(ofono_dbus "$modem" org.ofono.SimManager.GetProperties)"; then
            echo "Couldn't get properties of SIM $modem; skipping" >&2
            continue
        fi
        if ! HERE_SIM_MCC=$(get_string "$data" "MobileCountryCode"); then
            echo "Couldn't find MobileCountryCode for SIM $modem; skipping" >&2
            continue
        fi
        if ! HERE_SIM_MNC=$(get_string "$data" "MobileNetworkCode"); then
            echo "Couldn't find MobileNetworkCode for SIM $modem; skipping" >&2
            continue
        fi
        export HERE_SIM_MCC HERE_SIM_MNC
        return 0
    done
    die "No modem/SIM had all required properties; giving up"
}

here_dummy_ofono_env() {
        HERE_IMEI_FRAGMENT="00000000"
        export HERE_IMEI_FRAGMENT
        HERE_SIM_MCC=""
        HERE_SIM_MNC=""
        export HERE_SIM_MCC HERE_SIM_MNC
}
