# vim: ts=2
{
  config,
  pkgs,
  lib,
  stdenv,
  generate_extensions,
  user_js,
  system,
  ...
}: let
  bookmarks = [
    {
      name = "Feed - Piped";
      url = "https://piped.video/feed";
    }

    {
      name = "DeepL Translate";
      url = "https://www.deepl.com/translator#en/de/test";
    }
  ];
  firefoxBookmarksFile = bookmarks: let
    indent = level:
      lib.concatStringsSep "" (map (lib.const "  ") (lib.range 1 level));

    bookmarkToHTML = indentLevel: bookmark: ''
      ${indent indentLevel}<DT><A HREF="${
        lib.escapeXML bookmark.url
      }" ADD_DATE="0" LAST_MODIFIED="0">${lib.escapeXML bookmark.name}</A>'';

    directoryToHTML = indentLevel: directory: ''
      ${indent indentLevel}<DT>${
        if directory.toolbar
        then ''<H3 PERSONAL_TOOLBAR_FOLDER="true">Bookmarks Toolbar''
        else "<H3>${lib.escapeXML directory.name}"
      }</H3>
      ${indent indentLevel}<DL><p>
      ${allItemsToHTML (indentLevel + 1) directory.bookmarks}
      ${indent indentLevel}</p></DL>'';

    itemToHTMLOrRecurse = indentLevel: item:
      if item ? "url"
      then bookmarkToHTML indentLevel item
      else directoryToHTML indentLevel item;

    allItemsToHTML = indentLevel: bookmarks:
      lib.concatStringsSep "\n"
      (map (itemToHTMLOrRecurse indentLevel) bookmarks);

    bookmarkEntries = allItemsToHTML 1 bookmarks;
  in
    pkgs.writeText "firefox-bookmarks.html" ''
      <!DOCTYPE NETSCAPE-Bookmark-file-1>
      <!-- This is an automatically generated file.
        It will be read and overwritten.
        DO NOT EDIT! -->
      <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=UTF-8">
      <TITLE>Bookmarks</TITLE>
      <H1>Bookmarks Menu</H1>

      <DL><p>
          <DT><H3 ADD_DATE="0" LAST_MODIFIED="0" PERSONAL_TOOLBAR_FOLDER="true">Bookmarks Toolbar</H3>
          <DL><p>
          ${bookmarkEntries}
          </DL><p>
      </p></DL>
    '';
  userChrome = builtins.readFile ./chrome/userChrome.css;

  user_js_override = pkgs.writeText "user.override.js" (builtins.readFile ./settings/override.js);
  user_js_nix = pkgs.runCommand "user.js" {} ''
    mkdir $out;
    cat "${user_js}/user.js" > $out/user.js;
    cat "${user_js_override}" >> $out/user.js;

    cat << EOF >> $out/user.js;
    // My bookmarks
    user_pref("browser.bookmarks.file", "${toString (firefoxBookmarksFile bookmarks)}");
    user_pref("browser.places.importBookmarksHTML", true);

    // Allow my custom css
    user_pref("toolkit.legacyUserProfileCustomizations.stylesheets", true);

    // might improve performance TODO
    user_pref("gfx.webrender.all", true);

    // disable updates (pretty pointless with nix)
    user_pref("extensions.update.autoUpdateDefault", false);
    user_pref("extensions.update.enabled", false);
    user_pref("app.update.channel", "default");

    user_pref("browser.ctrlTab.recentlyUsedOrder", false);

    user_pref("browser.download.useDownloadDir", true);
    user_pref("browser.download.dir", "${config.home.homeDirectory}/media/downloads");
    user_pref("browser.download.folderList", 2); # TODO
    user_pref("browser.download.viewableInternally.typeWasRegistered.svg", true);
    user_pref("browser.download.viewableInternally.typeWasRegistered.webp", true);
    user_pref("browser.download.viewableInternally.typeWasRegistered.xml", true);

    // TODO what does this do?
    user_pref("browser.search.widget.inNavBar", true);

    user_pref("browser.shell.checkDefaultBrowser", false);
    user_pref("browser.tabs.loadInBackground", true);
    user_pref("browser.urlbar.placeholderName", "Brave");

    user_pref("general.autoScroll", true);

    // Set the tabs and bookmarks
    user_pref("browser.tabs.inTitlebar", 1);
    user_pref("browser.toolbars.bookmarks.visibility", "always");

    // Theme
    user_pref("extensions.activeThemeID", "firefox-alpenglow@mozilla.org");
    user_pref("extensions.extensions.activeThemeID", "firefox-alpenglow@mozilla.org");

    // highlight all entries when searching
    user_pref("findbar.highlightAll", true);

    // TODO
    //user_pref("extensions.webcompat.enable_picture_in_picture_overrides", true);
    //user_pref("extensions.webcompat.enable_shims", true);
    //user_pref("extensions.webcompat.perform_injections", true);
    //user_pref("extensions.webcompat.perform_ua_overrides", true);

    // onlykey / copied from a yubikey config
    //user_pref("security.webauth.u2f", true);
    //user_pref("security.webauth.webauthn", true);
    //user_pref("security.webauth.webauthn_enable_softtoken", true);
    //user_pref("security.webauth.webauthn_enable_usbtoken", true);
    EOF
  '';
  #"${strip_js_comments.app.${system}.default.program}" $out/user.js > $out/user_clean.js;
  #    echo "{" > $out/user.nix.tmp
  #    sed 's/user_pref(\(.*\)",\(.*\));/\1" = \2;/' $out/user_clean.js >> $out/user.nix.tmp;
  #    echo "}" >> $out/user.nix.tmp
  #    awk '!/"_user.js.parrot"/' $out/user.nix.tmp >> $out/user.nix; # delete duplicate keys

  extensions = builtins.map buildFirefoxXpiAddon (
    lib.attrValues (
      lib.importJSON ./settings/extensions.json
    )
  );

  # source: https://gitlab.com/rycee/nur-expressions/-/blob/master/pkgs/firefox-addons/default.nix
  buildFirefoxXpiAddon = {
    pname,
    version,
    addonId,
    url,
    sha256,
    #meta,
    ...
  }:
    pkgs.stdenv.mkDerivation {
      name = "${pname}-${version}";

      #inherit meta;

      src = builtins.fetchurl {inherit url sha256;};

      preferLocalBuild = true;
      allowSubstitutes = true;

      buildCommand = ''
        dst="$out/share/mozilla/extensions/{ec8030f7-c20a-464f-9b0e-13a3a9e97384}"
        mkdir -p "$dst"
        install -v -m644 "$src" "$dst/${addonId}.xpi"
      '';
    };

  settings = {
  };
in {
  home.packages = [
    pkgs.firefox-wayland
  ];
  home.sessionVariables = {
    # improve touch input & make scrolling smother
    MOZ_USE_XINPUT2 = "1";
    # improve wayland support
    MOZ_ENABLE_WAYLAND = 1;
  };
  xdg.mimeApps = {
    enable = true;
    defaultApplications = {
      "text/html" = ["firefox.desktop"];
      "x-scheme-handler/http" = ["firefox.desktop"];
      "x-scheme-handler/https" = ["firefox.desktop"];
      "x-scheme-handler/about" = ["firefox.desktop"];
      "x-scheme-handler/unknown" = ["firefox.desktop"];
    };
  };
  programs.firefox = {
    enable = true;
    package = pkgs.firefox;
    profiles."default" = {
      inherit extensions;
      isDefault = true;
      id = 0;
      name = "default";

      inherit userChrome;

      search = {
        default = "Brave Search";
        force = true;

        engines = {
          "Brave Search" = {
            urls = [{template = "https://search.brave.com/search?q={searchTerms}";}];
            iconUpdateURL = "https://raw.githubusercontent.com/brave/brave-core/master/components/brave_welcome_ui/components/images/lion_logo.svg";
            updateInterval = 24; # every day
            definedAliases = ["@bs"];
          };

          # NIX
          "Nix Packages" = {
            urls = [{template = "https://search.nixos.org/packages?type=packages&query={searchTerms}";}];
            icon = "${pkgs.nixos-icons}/share/icons/hicolor/scalable/apps/nix-snowflake.svg";
            definedAliases = ["@np"];
          };
          "Nix Options" = {
            urls = [{template = "https://search.nixos.org/options?type=options&query={searchTerms}";}];
            icon = "${pkgs.nixos-icons}/share/icons/hicolor/scalable/apps/nix-snowflake.svg";
            definedAliases = ["@no"];
          };
          "NixOS Wiki" = {
            urls = [{template = "https://nixos.wiki/index.php?search={searchTerms}";}];
            icon = "${pkgs.nixos-icons}/share/icons/hicolor/scalable/apps/nix-snowflake.svg";
            definedAliases = ["@nw"];
          };

          "Arch Wiki" = {
            urls = [{template = "https://wiki.archlinux.org/index.php?search={searchTerms}";}];
            iconUpdateURL = "https://upload.wikimedia.org/wikipedia/commons/a/a5/Archlinux-icon-crystal-64.svg";
            updateInterval = 24;
            definedAliases = ["@aw"];
          };

          # RUST
          "Rust std" = {
            urls = [{template = "https://doc.rust-lang.org/std/?search={searchTerms}";}];
            iconUpdateURL = "https://rustacean.net/assets/rustacean-orig-noshadow.svg";
            updateInterval = 24;
            definedAliases = ["@rs"];
          };

          "Google Scholar" = {
            urls = [{template = "https://scholar.google.com/scholar?hl=en&q={searchTerms}";}];
            iconUpdateURL = "https://scholar.google.com/favicon.ico";
            updateInterval = 24;
            definedAliases = ["@gs"];
          };
          "Wikipedia" = {
            urls = [{template = "https://en.wikipedia.org/wiki/{searchTerms}";}];
            iconUpdateURL = "https://upload.wikimedia.org/wikipedia/en/8/80/Wikipedia-logo-v2.svg";
            updateInterval = 24;
            definedAliases = ["@wp"];
          };

          "Wikipedia (en)".metaData.hidden = true;
          "DuckDuckGo".metaData.hidden = true;
          "Bing".metaData.hidden = true;
          "Google".metaData.hidden = true;
          "Amazon.de".metaData.hidden = true;
        };
      };

      bookmarks = [];
      inherit settings;
      extraConfig = builtins.readFile "${user_js_nix}/user.js";
    };
  };
}