{
  config,
  lib,
  pkgs,
  ...
}:
let
  inherit (lib)
    literalExpression
    mkIf
    mkMerge
    mkOption
    types
    ;

  cfg = config.programs.zed-editor;
  jsonFormat = pkgs.formats.json { };
  json5 = pkgs.python3Packages.toPythonApplication pkgs.python3Packages.json5;
  impureConfigMerger = empty: jqOperation: path: staticSettings: ''
    mkdir -p $(dirname ${lib.escapeShellArg path})
    if [ ! -e ${lib.escapeShellArg path} ]; then
      # No file? Create it
      echo ${lib.escapeShellArg empty} > ${lib.escapeShellArg path}
    fi
    dynamic="$(${lib.getExe json5} --as-json ${lib.escapeShellArg path} 2>/dev/null || echo ${lib.escapeShellArg empty})"
    static="$(cat ${lib.escapeShellArg staticSettings})"
    config="$(${lib.getExe pkgs.jq} -n ${lib.escapeShellArg jqOperation} --argjson dynamic "$dynamic" --argjson static "$static")"
    printf '%s\n' "$config" > ${lib.escapeShellArg path}
    unset config
  '';

  mergedSettings =
    cfg.userSettings
    // (lib.optionalAttrs (builtins.length cfg.extensions > 0) {
      # this part by @cmacrae
      auto_install_extensions = lib.genAttrs cfg.extensions (_: true);
    });
in
{
  meta.maintainers = [ lib.hm.maintainers.libewa ];

  options = {
    # TODO: add vscode option parity (installing extensions, configuring
    # keybinds with nix etc.)
    programs.zed-editor = {
      enable = lib.mkEnableOption "Zed, the high performance, multiplayer code editor from the creators of Atom and Tree-sitter";

      package = lib.mkPackageOption pkgs "zed-editor" { nullable = true; };

      extraPackages = mkOption {
        type = with types; listOf package;
        default = [ ];
        example = literalExpression "[ pkgs.nixd ]";
        description = "Extra packages available to Zed.";
      };

      mutableUserSettings = mkOption {
        type = types.bool;
        default = true;
        example = false;
        description = ''
          Whether user settings (settings.json) can be updated by zed.
        '';
      };

      mutableUserKeymaps = mkOption {
        type = types.bool;
        default = true;
        example = false;
        description = ''
          Whether user keymaps (keymap.json) can be updated by zed.
        '';
      };

      mutableUserTasks = mkOption {
        type = types.bool;
        default = true;
        example = false;
        description = ''
          Whether user tasks (tasks.json) can be updated by zed.
        '';
      };

      userSettings = mkOption {
        type = jsonFormat.type;
        default = { };
        example = literalExpression ''
          {
            features = {
              copilot = false;
            };
            telemetry = {
              metrics = false;
            };
            vim_mode = false;
            ui_font_size = 16;
            buffer_font_size = 16;
          }
        '';
        description = ''
          Configuration written to Zed's {file}`settings.json`.
        '';
      };

      userKeymaps = mkOption {
        type = jsonFormat.type;
        default = [ ];
        example = literalExpression ''
          [
            {
              context = "Workspace";
              bindings = {
                ctrl-shift-t = "workspace::NewTerminal";
              };
            };
          ]
        '';
        description = ''
          Configuration written to Zed's {file}`keymap.json`.
        '';
      };

      userTasks = mkOption {
        type = jsonFormat.type;
        default = [ ];
        example = literalExpression ''
          [
            {
              label = "Format Code";
              command = "nix";
              args = [ "fmt" "$ZED_WORKTREE_ROOT" ];
            }
          ]
        '';
        description = ''
          Configuration written to Zed's {file}`tasks.json`.

          [List of tasks](https://zed.dev/docs/tasks) that can be run from the
          command palette.
        '';
      };

      extensions = mkOption {
        type = types.listOf types.str;
        default = [ ];
        example = literalExpression ''
          [ "swift" "nix" "xy-zed" ]
        '';
        description = ''
          A list of the extensions Zed should install on startup.
          Use the name of a repository in the [extension list](https://github.com/zed-industries/extensions/tree/main/extensions).
        '';
      };

      installRemoteServer = mkOption {
        type = types.bool;
        default = false;
        example = true;
        description = ''
          Whether to symlink the Zed's remote server binary to the expected
          location. This allows remotely connecting to this system from a
          distant Zed client.

          For more information, consult the
          ["Remote Server" section](https://wiki.nixos.org/wiki/Zed#Remote_Server)
          in the wiki.
        '';
      };

      themes = mkOption {
        description = ''
          Each theme is written to
          {file}`$XDG_CONFIG_HOME/zed/themes/theme-name.json`
          where the name of each attribute is the theme-name

          See <https://zed.dev/docs/extensions/themes> for the structure of a
          Zed theme
        '';
        type = types.attrsOf (
          types.oneOf [
            jsonFormat.type
            types.path
            types.lines
          ]
        );
        default = { };
      };
    };
  };

  config = mkIf cfg.enable {
    home.packages = mkIf (cfg.package != null) (
      if cfg.extraPackages != [ ] then
        [
          (pkgs.symlinkJoin {
            name = "${lib.getName cfg.package}-wrapped-${lib.getVersion cfg.package}";
            paths = [ cfg.package ];
            preferLocalBuild = true;
            nativeBuildInputs = [ pkgs.makeWrapper ];
            postBuild = ''
              wrapProgram $out/bin/zeditor \
                --suffix PATH : ${lib.makeBinPath cfg.extraPackages}
            '';
          })
        ]
      else
        [ cfg.package ]
    );

    home.file = mkIf (cfg.installRemoteServer && (cfg.package ? remote_server)) (
      let
        inherit (cfg.package) version remote_server;
        binaryName = "zed-remote-server-stable-${version}";
      in
      {
        ".zed_server/${binaryName}".source = lib.getExe' remote_server binaryName;
      }
    );

    home.activation = mkMerge [
      (mkIf (cfg.mutableUserSettings && mergedSettings != { }) {
        zedSettingsActivation = lib.hm.dag.entryAfter [ "linkGeneration" ] (
          impureConfigMerger "{}" "$dynamic * $static" "${config.xdg.configHome}/zed/settings.json" (
            jsonFormat.generate "zed-user-settings" mergedSettings
          )
        );
      })
      (mkIf (cfg.mutableUserKeymaps && cfg.userKeymaps != [ ]) {
        zedKeymapActivation = lib.hm.dag.entryAfter [ "linkGeneration" ] (
          impureConfigMerger "[]"
            "$dynamic + $static | group_by(.context) | map(reduce .[] as $item ({}; . * $item))"
            "${config.xdg.configHome}/zed/keymap.json"
            (jsonFormat.generate "zed-user-keymaps" cfg.userKeymaps)
        );
      })
      (mkIf (cfg.mutableUserTasks && cfg.userTasks != [ ]) {
        zedTasksActivation = lib.hm.dag.entryAfter [ "linkGeneration" ] (
          impureConfigMerger "[]"
            "$dynamic + $static | group_by(.label) | map(reduce .[] as $item ({}; . * $item))"
            "${config.xdg.configHome}/zed/tasks.json"
            (jsonFormat.generate "zed-user-tasks" cfg.userTasks)
        );
      })
    ];

    xdg.configFile = mkMerge [
      (lib.mapAttrs' (
        n: v:
        lib.nameValuePair "zed/themes/${n}.json" {
          source =
            if lib.isString v then
              pkgs.writeText "zed-theme-${n}" v
            else if builtins.isPath v || lib.isStorePath v then
              v
            else
              jsonFormat.generate "zed-theme-${n}" v;
        }
      ) cfg.themes)
      (mkIf (!cfg.mutableUserSettings && mergedSettings != { }) {
        "zed/settings.json".source = jsonFormat.generate "zed-user-settings" mergedSettings;
      })
      (mkIf (!cfg.mutableUserKeymaps && cfg.userKeymaps != { }) {
        "zed/keymap.json".source = jsonFormat.generate "zed-user-keymaps" cfg.userKeymaps;
      })
      (mkIf (!cfg.mutableUserTasks && cfg.userTasks != [ ]) {
        "zed/tasks.json".source = jsonFormat.generate "zed-user-tasks" cfg.userTasks;
      })
    ];

    assertions = [
      {
        assertion = cfg.extraPackages != [ ] -> cfg.package != null;
        message = "{option}programs.zed-editor.extraPackages requires non null {option}programs.zed-editor.package";
      }
    ];
  };
}
