#!/usr/bin/env bash

set -euo pipefail

script_name="${0##*/}"
firefox_bin="${FIREFOX_BIN:-firefox-devedition}"
profile_dir="${FIREFOX_FOCUS_PROFILE_DIR:-$HOME/.mozilla/firefox/focus-mode.profile}"
extension_dir="${FIREFOX_FOCUS_EXTENSION_DIR:-$HOME/Documents/git/firefox-focus}"
extension_id="firefox-focus-mode@hunner.dev"
user_js_path="$profile_dir/user.js"
user_chrome_path="$profile_dir/chrome/userChrome.css"
extension_xpi="$profile_dir/extensions/$extension_id.xpi"
legacy_extension_link="$profile_dir/extensions/$extension_id"
kiosk_mode=false

detect_firefox_version() {
  "$firefox_bin" --version 2>/dev/null || true
}

warn_about_unsigned_install() {
  local version_output="$1"
  local firefox_name

  firefox_name="$(basename "$firefox_bin")"

  case "$version_output" in
    *"Developer Edition"*|*"Nightly"*|*"ESR"*)
      return
      ;;
  esac

  case "$firefox_name" in
    firefox-devedition|firefox-developer-edition)
      return
      ;;
  esac

  cat >&2 <<EOF
Note: persistent local add-on install is usually blocked in standard Firefox
release builds like "$version_output". The Focus profile styling will still
apply, but you may still need "Load Temporary Add-on" in about:debugging unless
you use a signed .xpi or a Firefox channel that allows local unsigned installs.
EOF
}

usage() {
  cat <<EOF
Usage: $script_name [-k|--kiosk] [url-or-search] [firefox args...]

Launch Firefox with the dedicated Focus profile and the local Firefox Focus
extension linked into that profile.

Environment overrides:
  FIREFOX_BIN                  Firefox binary to execute (defaults to firefox-devedition)
  FIREFOX_FOCUS_PROFILE_DIR    Dedicated profile directory
  FIREFOX_FOCUS_EXTENSION_DIR  Firefox Focus extension checkout
EOF
}

urlencode() {
  local input="$1"
  local output=""
  local i char hex

  for ((i = 0; i < ${#input}; i++)); do
    char="${input:i:1}"
    case "$char" in
      [a-zA-Z0-9.~_-])
        output+="$char"
        ;;
      ' ')
        output+='%20'
        ;;
      *)
        printf -v hex '%%%02X' "'$char"
        output+="$hex"
        ;;
    esac
  done

  printf '%s\n' "$output"
}

looks_like_url_without_schema() {
  local target="$1"

  [[ ! "$target" =~ [[:space:]] ]] || return 1
  [[ "$target" =~ ^localhost([:/?#].*)?$ ]] && return 0
  [[ "$target" =~ ^([0-9]{1,3}\.){3}[0-9]{1,3}([:/?#].*)?$ ]] && return 0
  [[ "$target" =~ ^([[:alnum:]][[:alnum:]-]*\.)+[[:alpha:]]{2,}([:/?#].*)?$ ]]
}

normalize_target() {
  local raw_target="$1"

  if [[ -z "$raw_target" ]]; then
    printf '%s\n' ""
    return
  fi

  if [[ "$raw_target" =~ ^[[:alpha:]][[:alnum:]+.-]*: ]]; then
    printf '%s\n' "$raw_target"
  elif looks_like_url_without_schema "$raw_target"; then
    printf 'https://%s\n' "$raw_target"
  else
    printf 'https://search.hunner.dev/search?q=%s\n' "$(urlencode "$raw_target")"
  fi
}

write_user_js() {
  mkdir -p "$profile_dir"

  cat >"$user_js_path" <<EOF
user_pref("app.update.auto", false);
user_pref("browser.discovery.enabled", false);
user_pref("browser.newtabpage.activity-stream.feeds.section.topstories", false);
user_pref("browser.newtabpage.activity-stream.feeds.topsites", false);
user_pref("browser.newtabpage.activity-stream.showSponsored", false);
user_pref("browser.newtabpage.activity-stream.showSponsoredTopSites", false);
user_pref("browser.policies.applied", true);
user_pref("browser.sessionstore.resume_from_crash", false);
user_pref("browser.shell.checkDefaultBrowser", false);
user_pref("browser.startup.homepage", "about:newtab");
user_pref("browser.startup.page", 1);
user_pref("browser.toolbars.bookmarks.visibility", "never");
user_pref("browser.tabs.closeWindowWithLastTab", false);
user_pref("browser.tabs.warnOnClose", false);
user_pref("browser.uiCustomization.state", "{\"placements\":{\"widget-overflow-fixed-list\":[],\"unified-extensions-area\":[],\"nav-bar\":[\"back-button\",\"forward-button\",\"stop-reload-button\",\"urlbar-container\",\"firefox-focus-mode_hunner_dev-browser-action\",\"unified-extensions-button\"],\"toolbar-menubar\":[\"menubar-items\"],\"TabsToolbar\":[\"firefox-view-button\",\"tabbrowser-tabs\",\"new-tab-button\",\"alltabs-button\"],\"vertical-tabs\":[],\"PersonalToolbar\":[]},\"seen\":[\"developer-button\",\"screenshot-button\",\"firefox-focus-mode_hunner_dev-browser-action\"],\"dirtyAreaCache\":[\"nav-bar\",\"vertical-tabs\",\"toolbar-menubar\",\"TabsToolbar\",\"PersonalToolbar\",\"unified-extensions-area\"],\"currentVersion\":23,\"newElementCount\":2}");
user_pref("datareporting.healthreport.uploadEnabled", false);
user_pref("extensions.autoDisableScopes", 0);
user_pref("extensions.enabledScopes", 5);
user_pref("extensions.installDistroAddons", true);
user_pref("xpinstall.signatures.required", false);
user_pref("privacy.clearOnShutdown.cache", true);
user_pref("privacy.clearOnShutdown.cookies", true);
user_pref("privacy.clearOnShutdown.downloads", true);
user_pref("privacy.clearOnShutdown.formdata", true);
user_pref("privacy.clearOnShutdown.history", true);
user_pref("privacy.clearOnShutdown.offlineApps", true);
user_pref("privacy.clearOnShutdown.sessions", true);
user_pref("privacy.donottrackheader.enabled", true);
user_pref("privacy.sanitize.sanitizeOnShutdown", true);
user_pref("privacy.sanitize.timeSpan", 0);
user_pref("signon.rememberSignons", false);
user_pref("toolkit.legacyUserProfileCustomizations.stylesheets", true);
EOF
}

write_user_chrome() {
  mkdir -p "$(dirname "$user_chrome_path")"

  cat >"$user_chrome_path" <<'EOF'
/* Focus profile chrome trimming */
#PersonalToolbar,
#TabsToolbar {
  visibility: collapse !important;
}

#sidebar-button,
#fxa-toolbar-menu-button,
#downloads-button {
  display: none !important;
}

#nav-bar {
  border-top-width: 0 !important;
}
EOF
}

package_extension() {
  if [[ ! -f "$extension_dir/manifest.json" ]]; then
    printf 'Extension manifest not found at %s\n' "$extension_dir/manifest.json" >&2
    exit 1
  fi

  mkdir -p "$profile_dir/extensions"
  rm -f "$legacy_extension_link"

  (
    cd "$extension_dir"
    zip -qr "$extension_xpi" \
      manifest.json \
      background.js \
      home.html \
      home.css \
      home.js \
      popup.html \
      popup.css \
      popup.js \
      options.html \
      options.css \
      options.js \
      theme.css \
      icons
  )
}

while [[ $# -gt 0 ]]; do
  case "$1" in
    -k|--kiosk)
      kiosk_mode=true
      shift
      ;;
    -h|--help)
      usage
      exit 0
      ;;
    --)
      shift
      break
      ;;
    -*)
      printf 'Unknown option: %s\n\n' "$1" >&2
      usage >&2
      exit 1
      ;;
    *)
      break
      ;;
  esac
done

target="${1:-}"
if [[ $# -gt 0 ]]; then
  shift
fi

if ! command -v "$firefox_bin" >/dev/null 2>&1; then
  printf 'Firefox binary not found: %s\n' "$firefox_bin" >&2
  exit 1
fi

firefox_version="$(detect_firefox_version)"

write_user_js
write_user_chrome
package_extension
warn_about_unsigned_install "$firefox_version"

firefox_args=(
  --new-instance
  --profile "$profile_dir"
)

if "$kiosk_mode"; then
  firefox_args+=(--kiosk)
fi

target_url="$(normalize_target "$target")"

if [[ -n "$target_url" ]]; then
  exec "$firefox_bin" \
    "${firefox_args[@]}" \
    --new-window "$target_url" \
    "$@"
fi

exec "$firefox_bin" \
  "${firefox_args[@]}" \
  --new-window \
  "$@"
