#!/bin/sh
# browser-darkmode - use your own colours in the Sailfish browsers
# Usage: browser-darkmode [profile] [never|missing|always|status|apply]
#        browser-darkmode detect
#
# profile is one of:
#   browser          the stock browser
#   browser-next     the ESR 140 build
#   browser-next153  the ESR 153 build
# and defaults to the newest one that has a profile directory.
#
# Modes map to browser.display.document_color_use:
#   never    =0 - pages decide (stock behaviour)
#   missing  =1 - your colours only where the page sets none
#   always   =2 - your colours everywhere, page colours ignored
#
# "always" is the only setting that gives a dark page on a site that offers
# none, at the price of sites that lean on their own colours looking wrong.
#
# Mode and colours live in dconf under /apps/sailfish-browser-darkmode/<profile>/
# so each browser keeps its own. Only that browser's user.js is edited, between
# two marker comments; it is read at every start and never rewritten.

DCONF_ROOT="/apps/sailfish-browser-darkmode"
MARK_BEGIN="// >>> browser-darkmode"
MARK_END="// <<< browser-darkmode"
PROFILES="browser-next153 browser-next browser"

moz_dir() { echo "$HOME/.local/share/org.sailfishos/$1/.mozilla"; }

# write the list of installed browsers to dconf for the Settings page.
# No arrays here: /bin/bash on the device can be busybox ash, which has none.
detect() {
    list=""
    for p in $PROFILES; do
        if [ -d "$(moz_dir "$p")" ]; then
            [ -n "$list" ] && list="$list, "
            list="$list'$p'"
            echo "$p"
        fi
    done
    dconf write "$DCONF_ROOT/available" "[$list]" 2>/dev/null
}

default_profile() {
    for p in $PROFILES; do
        [ -d "$(moz_dir "$p")" ] && { echo "$p"; return; }
    done
    echo browser-next153
}

colour() {
    key="$1"; fallback="$2"
    v=$(dconf read "$DCONF_ROOT/$PROFILE/$key" 2>/dev/null | tr -d "'")
    case "$v" in
        \#[0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F]) echo "$v" ;;
        *) echo "$fallback" ;;
    esac
}

name_of() {
    case "$1" in
        1) echo missing ;;
        2) echo always ;;
        *) echo never ;;
    esac
}

# first argument may be a profile; otherwise fall back to the newest installed
case "$1" in
    browser|browser-next|browser-next153) PROFILE="$1"; shift ;;
    detect) detect; exit 0 ;;
    *) PROFILE=$(default_profile) ;;
esac

MOZ=$(moz_dir "$PROFILE")
USERJS="$MOZ/user.js"

[ -d "$MOZ" ] || { echo "error: $MOZ not found - start that browser once first" >&2; exit 1; }

cur=""
if [ -f "$USERJS" ] && grep -qF "$MARK_BEGIN" "$USERJS"; then
    cur=$(sed -n 's/.*"browser.display.document_color_use", \([0-9]\).*/\1/p' "$USERJS" | tail -1)
fi
[ -n "$cur" ] || cur=$(dconf read "$DCONF_ROOT/$PROFILE/mode" 2>/dev/null | tr -dc '0-9')
[ -n "$cur" ] || cur=0

mode="${1:-status}"
case "$mode" in
    status) name_of "$cur"; exit 0 ;;
    apply)  value="$cur" ;;
    never)   value=0 ;;
    missing) value=1 ;;
    always)  value=2 ;;
    *) echo "Usage: browser-darkmode [profile] [never|missing|always|status|apply]" >&2; exit 2 ;;
esac

BG=$(colour background '#000000')
FG=$(colour foreground '#ffffff')
LINK=$(colour link '#ffff11')
VISITED=$(colour visited '#55aa8b')
FOCUS=$(colour focus '#118822')

[ -f "$USERJS" ] && sed -i "\|^$MARK_BEGIN\$|,\|^$MARK_END\$|d" "$USERJS"

# the block is written for "never" too: prefs.js keeps the last value, so the
# stock behaviour has to be stated rather than just left out
cat >> "$USERJS" <<EOF
$MARK_BEGIN
user_pref("browser.display.document_color_use", $value);
user_pref("browser.display.background_color", "$BG");
user_pref("browser.display.foreground_color", "$FG");
user_pref("browser.anchor_color", "$LINK");
user_pref("browser.visited_color", "$VISITED");
user_pref("browser.display.focus_background_color", "$FOCUS");
user_pref("browser.display.suppress_canvas_background_image_on_forced_colors", false);
$MARK_END
EOF

dconf write "$DCONF_ROOT/$PROFILE/mode" "$value" 2>/dev/null
detect > /dev/null
echo "$PROFILE: $(name_of "$value") - restart that browser to apply"
