text: "use strict";
  
  const {strict: assert} = require("assert");
  
  const autosize = require("autosize");
  
  const {$t} = require("../zjsunit/i18n");
  const {mock_cjs, set_global, zrequire} = require("../zjsunit/namespace");
  const {run_test} = require("../zjsunit/test");
  const $ = require("../zjsunit/zjquery");
  
  mock_cjs("jquery", $);
  
  set_global("document", {
      execCommand() {
          return false;
      },
  });
  
  const compose_ui = zrequire("compose_ui");
  const people = zrequire("people");
  const user_status = zrequire("user_status");
  
  const alice = {
      email: "alice@zulip.com",
      user_id: 101,
      full_name: "Alice",
  };
  const bob = {
      email: "bob@zulip.com",
      user_id: 102,
      full_name: "Bob",
  };
  
  people.add_active_user(alice);
  people.add_active_user(bob);
  
  function make_textbox(s) {
      // Simulate a jQuery textbox for testing purposes.
      const widget = {};
  
      widget.s = s;
      widget.focused = false;
  
      widget.caret = function (arg) {
          if (typeof arg === "number") {
              widget.pos = arg;
              return this;
          }
  
          if (arg) {
              widget.insert_pos = widget.pos;
              widget.insert_text = arg;
              const before = widget.s.slice(0, widget.pos);
              const after = widget.s.slice(widget.pos);
              widget.s = before + arg + after;
              widget.pos += arg.length;
              return this;
          }
  
          return widget.pos;
      };
  
      widget.val = function (new_val) {
          if (new_val) {
              widget.s = new_val;
              return this;
          }
          return widget.s;
      };
  
      widget.trigger = function (type) {
          if (type === "focus") {
              widget.focused = true;
          } else if (type === "blur") {
              widget.focused = false;
          }
          return this;
      };
  
      return widget;
  }
  
  run_test("autosize_textarea", (override) => {
      const textarea_autosized = {};
  
      override(autosize, "update", (textarea) => {
          textarea_autosized.textarea = textarea;
          textarea_autosized.autosized = true;
      });
  
      // Call autosize_textarea with an argument
      const container = "container-stub";
      compose_ui.autosize_textarea(container);
      assert.equal(textarea_autosized.textarea, container);
      assert(textarea_autosized.autosized);
  });
  
  run_test("insert_syntax_and_focus", () => {
      $("#compose-textarea").val("xyz ");
      $("#compose-textarea").caret = function (syntax) {
          if (syntax !== undefined) {
              $("#compose-textarea").val($("#compose-textarea").val() + syntax);
              return this;
          }
          return 4;
      };
      compose_ui.insert_syntax_and_focus(":octopus:");
      assert.equal($("#compose-textarea").caret(), 4);
      assert.equal($("#compose-textarea").val(), "xyz :octopus: ");
      assert($("#compose-textarea").is_focused());
  });
  
  run_test("smart_insert", () => {
      let textbox = make_textbox("abc");
      textbox.caret(4);
  
      compose_ui.smart_insert(textbox, ":smile:");
      assert.equal(textbox.insert_pos, 4);
      assert.equal(textbox.insert_text, " :smile: ");
      assert.equal(textbox.val(), "abc :smile: ");
      assert(textbox.focused);
  
      textbox.trigger("blur");
      compose_ui.smart_insert(textbox, ":airplane:");
      assert.equal(textbox.insert_text, ":airplane: ");
      assert.equal(textbox.val(), "abc :smile: :airplane: ");
      assert(textbox.focused);
  
      textbox.caret(0);
      textbox.trigger("blur");
      compose_ui.smart_insert(textbox, ":octopus:");
      assert.equal(textbox.insert_text, ":octopus: ");
      assert.equal(textbox.val(), ":octopus: abc :smile: :airplane: ");
      assert(textbox.focused);
  
      textbox.caret(textbox.val().length);
      textbox.trigger("blur");
      compose_ui.smart_insert(textbox, ":heart:");
      assert.equal(textbox.insert_text, ":heart: ");
      assert.equal(textbox.val(), ":octopus: abc :smile: :airplane: :heart: ");
      assert(textbox.focused);
  
      // Test handling of spaces for ```quote
      textbox = make_textbox("");
      textbox.caret(0);
      textbox.trigger("blur");
      compose_ui.smart_insert(textbox, "```quote\nquoted message\n```\n");
      assert.equal(textbox.insert_text, "```quote\nquoted message\n```\n");
      assert.equal(textbox.val(), "```quote\nquoted message\n```\n");
      assert(textbox.focused);
  
      textbox = make_textbox("");
      textbox.caret(0);
      textbox.trigger("blur");
      compose_ui.smart_insert(textbox, "[Quoting…]\n");
      assert.equal(textbox.insert_text, "[Quoting…]\n");
      assert.equal(textbox.val(), "[Quoting…]\n");
      assert(textbox.focused);
  
      textbox = make_textbox("abc");
      textbox.caret(3);
      textbox.trigger("blur");
      compose_ui.smart_insert(textbox, " test with space");
      assert.equal(textbox.insert_text, " test with space ");
      assert.equal(textbox.val(), "abc test with space ");
      assert(textbox.focused);
  
      // Note that we don't have any special logic for strings that are
      // already surrounded by spaces, since we are usually inserting things
      // like emojis and file links.
  });
  
  run_test("replace_syntax", () => {
      $("#compose-textarea").val("abcabc");
  
      compose_ui.replace_syntax("a", "A");
      assert.equal($("#compose-textarea").val(), "Abcabc");
  
      compose_ui.replace_syntax(/b/g, "B");
      assert.equal($("#compose-textarea").val(), "ABcaBc");
  
      // Verify we correctly handle `$`s in the replacement syntax
      compose_ui.replace_syntax("Bca", "$$\\pi$$");
      assert.equal($("#compose-textarea").val(), "A$$\\pi$$Bc");
  });
  
  run_test("compute_placeholder_text", () => {
      let opts = {
          message_type: "stream",
          stream: "",
          topic: "",
          private_message_recipient: "",
      };
  
      // Stream narrows
      assert.equal(
          compose_ui.compute_placeholder_text(opts),
          $t({defaultMessage: "Compose your message here"}),
      );
  
      opts.stream = "all";
      assert.equal(compose_ui.compute_placeholder_text(opts), $t({defaultMessage: "Message #all"}));
  
      opts.topic = "Test";
      assert.equal(
          compose_ui.compute_placeholder_text(opts),
          $t({defaultMessage: "Message #all > Test"}),
      );
  
      // PM Narrows
      opts = {
          message_type: "private",
          stream: "",
          topic: "",
          private_message_recipient: "",
      };
      assert.equal(
          compose_ui.compute_placeholder_text(opts),
          $t({defaultMessage: "Compose your message here"}),
      );
  
      opts.private_message_recipient = "bob@zulip.com";
      user_status.set_status_text({
          user_id: bob.user_id,
          status_text: "out to lunch",
      });
      assert.equal(
          compose_ui.compute_placeholder_text(opts),
          $t({defaultMessage: "Message Bob (out to lunch)"}),
      );
  
      opts.private_message_recipient = "alice@zulip.com";
      user_status.set_status_text({
          user_id: alice.user_id,
          status_text: "",
      });
      assert.equal(compose_ui.compute_placeholder_text(opts), $t({defaultMessage: "Message Alice"}));
  
      // Group PM
      opts.private_message_recipient = "alice@zulip.com,bob@zulip.com";
      assert.equal(
          compose_ui.compute_placeholder_text(opts),
          $t({defaultMessage: "Message Alice, Bob"}),
      );
  });
  