// Copyright 2014 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "extensions/common/message_bundle.h"

#include <stddef.h>

#include <array>
#include <memory>
#include <string>
#include <string_view>
#include <utility>
#include <vector>

#include "base/i18n/rtl.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "base/values.h"
#include "extensions/common/error_utils.h"
#include "extensions/common/extension_l10n_util.h"
#include "extensions/common/manifest_constants.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace extensions {

namespace errors = manifest_errors;

class MessageBundleTest : public testing::Test {
 protected:
  enum BadDictionary {
    INVALID_NAME,
    NAME_NOT_A_TREE,
    EMPTY_NAME_TREE,
    MISSING_MESSAGE,
    PLACEHOLDER_NOT_A_TREE,
    EMPTY_PLACEHOLDER_TREE,
    CONTENT_MISSING,
    MESSAGE_PLACEHOLDER_DOESNT_MATCH,
  };

  void CreateContentTree(const std::string& name,
                         const std::string& content,
                         base::Value::Dict& dict) {
    base::Value::Dict content_tree;
    content_tree.Set(MessageBundle::kContentKey, content);
    dict.Set(name, std::move(content_tree));
  }

  void CreatePlaceholdersTree(base::Value::Dict& dict) {
    base::Value::Dict placeholders_tree;
    CreateContentTree("a", "A", placeholders_tree);
    CreateContentTree("b", "B", placeholders_tree);
    CreateContentTree("c", "C", placeholders_tree);
    dict.Set(MessageBundle::kPlaceholdersKey, std::move(placeholders_tree));
  }

  void CreateMessageTree(const std::string& name,
                         const std::string& message,
                         bool create_placeholder_subtree,
                         base::Value::Dict& dict) {
    base::Value::Dict message_tree;
    if (create_placeholder_subtree) {
      CreatePlaceholdersTree(message_tree);
    }
    message_tree.Set(MessageBundle::kMessageKey, message);
    dict.Set(name, std::move(message_tree));
  }

  base::Value::Dict CreateGoodDictionary() {
    base::Value::Dict dict;
    CreateMessageTree("n1", "message1 $a$ $b$", true, dict);
    CreateMessageTree("n2", "message2 $c$", true, dict);
    CreateMessageTree("n3", "message3", false, dict);
    return dict;
  }

  base::Value::Dict CreateBadDictionary(enum BadDictionary what_is_bad) {
    base::Value::Dict dict = CreateGoodDictionary();
    // Now remove/break things.
    switch (what_is_bad) {
      case INVALID_NAME:
        CreateMessageTree("n 5", "nevermind", false, dict);
        break;
      case NAME_NOT_A_TREE:
        dict.Set("n4", "whatever");
        break;
      case EMPTY_NAME_TREE:
        dict.Set("n4", base::Value::Dict());
        break;
      case MISSING_MESSAGE:
        RemoveDictionaryPath(dict, /*path=*/"n1", /*key*/ "message");
        break;
      case PLACEHOLDER_NOT_A_TREE:
        dict.SetByDottedPath("n1.placeholders", "whatever");
        break;
      case EMPTY_PLACEHOLDER_TREE:
        dict.SetByDottedPath("n1.placeholders", base::Value::Dict());
        break;
      case CONTENT_MISSING:
        RemoveDictionaryPath(dict, /*path=*/"n1.placeholders.a",
                             /*key=*/"content");
        break;
      case MESSAGE_PLACEHOLDER_DOESNT_MATCH:
        RemoveDictionaryPath(dict, /*path=*/"n1.placeholders", /*key=*/"a");
        base::Value::Dict* value = dict.FindDictByDottedPath("n1.placeholders");
        EXPECT_TRUE(value);
        CreateContentTree("x", "X", *value);
        break;
    }

    return dict;
  }

  void RemoveDictionaryPath(base::Value::Dict& dict,
                            std::string_view path,
                            std::string_view key) {
    base::Value::Dict* value = dict.FindDictByDottedPath(path);
    ASSERT_TRUE(value);
    value->Remove(key);
  }

  unsigned int ReservedMessagesCount() {
    // Update when adding new reserved messages.
    return 5U;
  }

  void CheckReservedMessages(MessageBundle* handler) {
    std::string ui_locale = extension_l10n_util::CurrentLocaleOrDefault();
    EXPECT_EQ(ui_locale,
              handler->GetL10nMessage(MessageBundle::kUILocaleKey));

    std::string text_dir = "ltr";
    if (base::i18n::GetTextDirectionForLocale(ui_locale.c_str()) ==
        base::i18n::RIGHT_TO_LEFT) {
      text_dir = "rtl";
    }

    EXPECT_EQ(text_dir, handler->GetL10nMessage(
        MessageBundle::kBidiDirectionKey));
  }

  bool AppendReservedMessages(const std::string& application_locale) {
    std::string error;
    return handler_->AppendReservedMessagesForLocale(
        application_locale, &error);
  }

  std::string CreateMessageBundle() {
    std::string error;
    handler_.reset(MessageBundle::Create(catalogs_, &error));

    return error;
  }

  void ClearDictionary() {
    handler_->dictionary_.clear();
  }

  std::unique_ptr<MessageBundle> handler_;
  MessageBundle::CatalogVector catalogs_;
};

TEST_F(MessageBundleTest, ReservedMessagesCount) {
  ASSERT_EQ(5U, ReservedMessagesCount());
}

TEST_F(MessageBundleTest, InitEmptyDictionaries) {
  CreateMessageBundle();
  EXPECT_TRUE(handler_.get() != nullptr);
  EXPECT_EQ(0U + ReservedMessagesCount(), handler_->size());
  CheckReservedMessages(handler_.get());
}

TEST_F(MessageBundleTest, InitGoodDefaultDict) {
  catalogs_.push_back(CreateGoodDictionary());
  CreateMessageBundle();

  EXPECT_TRUE(handler_.get() != nullptr);
  EXPECT_EQ(3U + ReservedMessagesCount(), handler_->size());

  EXPECT_EQ("message1 A B", handler_->GetL10nMessage("n1"));
  EXPECT_EQ("message2 C", handler_->GetL10nMessage("n2"));
  EXPECT_EQ("message3", handler_->GetL10nMessage("n3"));
  CheckReservedMessages(handler_.get());
}

TEST_F(MessageBundleTest, InitAppDictConsultedFirst) {
  catalogs_.push_back(CreateGoodDictionary());
  catalogs_.push_back(CreateGoodDictionary());

  base::Value::Dict& app_dict = catalogs_[0];
  // Flip placeholders in message of n1 tree.
  app_dict.SetByDottedPath("n1.message", "message1 $b$ $a$");
  // Remove one message from app dict.
  app_dict.Remove("n2");
  // Replace n3 with N3.
  app_dict.Remove("n3");
  CreateMessageTree("N3", "message3_app_dict", false, app_dict);

  CreateMessageBundle();

  EXPECT_TRUE(handler_.get() != nullptr);
  EXPECT_EQ(3U + ReservedMessagesCount(), handler_->size());

  EXPECT_EQ("message1 B A", handler_->GetL10nMessage("n1"));
  EXPECT_EQ("message2 C", handler_->GetL10nMessage("n2"));
  EXPECT_EQ("message3_app_dict", handler_->GetL10nMessage("n3"));
  CheckReservedMessages(handler_.get());
}

TEST_F(MessageBundleTest, InitBadAppDict) {
  catalogs_.push_back(CreateBadDictionary(INVALID_NAME));
  catalogs_.push_back(CreateGoodDictionary());

  std::string error = CreateMessageBundle();

  EXPECT_TRUE(handler_.get() == nullptr);
  EXPECT_EQ("Name of a key \"n 5\" is invalid. Only ASCII [a-z], "
            "[A-Z], [0-9] and \"_\" are allowed.", error);

  catalogs_[0] = CreateBadDictionary(NAME_NOT_A_TREE);
  handler_.reset(MessageBundle::Create(catalogs_, &error));
  EXPECT_TRUE(handler_.get() == nullptr);
  EXPECT_EQ("Not a valid tree for key n4.", error);

  catalogs_[0] = CreateBadDictionary(EMPTY_NAME_TREE);
  handler_.reset(MessageBundle::Create(catalogs_, &error));
  EXPECT_TRUE(handler_.get() == nullptr);
  EXPECT_EQ("There is no \"message\" element for key n4.", error);

  catalogs_[0] = CreateBadDictionary(MISSING_MESSAGE);
  handler_.reset(MessageBundle::Create(catalogs_, &error));
  EXPECT_TRUE(handler_.get() == nullptr);
  EXPECT_EQ("There is no \"message\" element for key n1.", error);

  catalogs_[0] = CreateBadDictionary(PLACEHOLDER_NOT_A_TREE);
  handler_.reset(MessageBundle::Create(catalogs_, &error));
  EXPECT_TRUE(handler_.get() == nullptr);
  EXPECT_EQ("Not a valid \"placeholders\" element for key n1.", error);

  catalogs_[0] = CreateBadDictionary(EMPTY_PLACEHOLDER_TREE);
  handler_.reset(MessageBundle::Create(catalogs_, &error));
  EXPECT_TRUE(handler_.get() == nullptr);
  EXPECT_EQ("Variable $a$ used but not defined.", error);

  catalogs_[0] = CreateBadDictionary(CONTENT_MISSING);
  handler_.reset(MessageBundle::Create(catalogs_, &error));
  EXPECT_TRUE(handler_.get() == nullptr);
  EXPECT_EQ("Invalid \"content\" element for key n1.", error);

  catalogs_[0] = CreateBadDictionary(MESSAGE_PLACEHOLDER_DOESNT_MATCH);
  handler_.reset(MessageBundle::Create(catalogs_, &error));
  EXPECT_TRUE(handler_.get() == nullptr);
  EXPECT_EQ("Variable $a$ used but not defined.", error);
}

TEST_F(MessageBundleTest, ReservedMessagesOverrideDeveloperMessages) {
  catalogs_.push_back(CreateGoodDictionary());

  base::Value::Dict& dict = catalogs_[0];
  CreateMessageTree(MessageBundle::kUILocaleKey, "x", false, dict);

  std::string error = CreateMessageBundle();

  EXPECT_TRUE(handler_.get() == nullptr);
  std::string expected_error = ErrorUtils::FormatErrorMessage(
      errors::kReservedMessageFound, MessageBundle::kUILocaleKey);
  EXPECT_EQ(expected_error, error);
}

TEST_F(MessageBundleTest, AppendReservedMessagesForLTR) {
  CreateMessageBundle();

  ASSERT_TRUE(handler_.get() != nullptr);
  ClearDictionary();
  ASSERT_TRUE(AppendReservedMessages("en_US"));

  EXPECT_EQ("en_US",
            handler_->GetL10nMessage(MessageBundle::kUILocaleKey));
  EXPECT_EQ("ltr", handler_->GetL10nMessage(
      MessageBundle::kBidiDirectionKey));
  EXPECT_EQ("rtl", handler_->GetL10nMessage(
      MessageBundle::kBidiReversedDirectionKey));
  EXPECT_EQ("left", handler_->GetL10nMessage(
      MessageBundle::kBidiStartEdgeKey));
  EXPECT_EQ("right", handler_->GetL10nMessage(
      MessageBundle::kBidiEndEdgeKey));
}

TEST_F(MessageBundleTest, AppendReservedMessagesForRTL) {
  CreateMessageBundle();

  ASSERT_TRUE(handler_.get() != nullptr);
  ClearDictionary();
  ASSERT_TRUE(AppendReservedMessages("he"));

  EXPECT_EQ("he",
            handler_->GetL10nMessage(MessageBundle::kUILocaleKey));
  EXPECT_EQ("rtl", handler_->GetL10nMessage(
      MessageBundle::kBidiDirectionKey));
  EXPECT_EQ("ltr", handler_->GetL10nMessage(
      MessageBundle::kBidiReversedDirectionKey));
  EXPECT_EQ("right", handler_->GetL10nMessage(
      MessageBundle::kBidiStartEdgeKey));
  EXPECT_EQ("left", handler_->GetL10nMessage(
      MessageBundle::kBidiEndEdgeKey));
}

TEST_F(MessageBundleTest, IsValidNameCheckValidCharacters) {
  EXPECT_TRUE(MessageBundle::IsValidName(std::string("a__BV_9")));
  EXPECT_TRUE(MessageBundle::IsValidName(std::string("@@a__BV_9")));
  EXPECT_FALSE(MessageBundle::IsValidName(std::string("$a__BV_9$")));
  EXPECT_FALSE(MessageBundle::IsValidName(std::string("a-BV-9")));
  EXPECT_FALSE(MessageBundle::IsValidName(std::string("a#BV!9")));
  EXPECT_FALSE(MessageBundle::IsValidName(std::string("a<b")));
}

struct ReplaceVariables {
  const char* original;
  const char* result;
  const char* error;
  const char* begin_delimiter;
  const char* end_delimiter;
  bool pass;
};

TEST(MessageBundle, ReplaceMessagesInText) {
  const char* kMessageBegin = MessageBundle::kMessageBegin;
  const char* kMessageEnd = MessageBundle::kMessageEnd;
  const char* kPlaceholderBegin = MessageBundle::kPlaceholderBegin;
  const char* kPlaceholderEnd = MessageBundle::kPlaceholderEnd;

  static auto test_cases = std::to_array<ReplaceVariables>({
      // Message replacement.
      {"This is __MSG_siMPle__ message", "This is simple message", "",
       kMessageBegin, kMessageEnd, true},
      {"This is __MSG_", "This is __MSG_", "", kMessageBegin, kMessageEnd,
       true},
      {"This is __MSG__simple__ message", "This is __MSG__simple__ message",
       "Variable __MSG__simple__ used but not defined.", kMessageBegin,
       kMessageEnd, false},
      {"__MSG_LoNg__", "A pretty long replacement", "", kMessageBegin,
       kMessageEnd, true},
      {"A __MSG_SimpLE__MSG_ a", "A simpleMSG_ a", "", kMessageBegin,
       kMessageEnd, true},
      {"A __MSG_simple__MSG_long__", "A simpleMSG_long__", "", kMessageBegin,
       kMessageEnd, true},
      {"A __MSG_simple____MSG_long__", "A simpleA pretty long replacement", "",
       kMessageBegin, kMessageEnd, true},
      {"__MSG_d1g1ts_are_ok__", "I are d1g1t", "", kMessageBegin, kMessageEnd,
       true},
      // Placeholder replacement.
      {"This is $sImpLe$ message", "This is simple message", "",
       kPlaceholderBegin, kPlaceholderEnd, true},
      {"This is $", "This is $", "", kPlaceholderBegin, kPlaceholderEnd, true},
      {"This is $$sIMPle$ message", "This is $simple message", "",
       kPlaceholderBegin, kPlaceholderEnd, true},
      {"$LONG_V$", "A pretty long replacement", "", kPlaceholderBegin,
       kPlaceholderEnd, true},
      {"A $simple$$ a", "A simple$ a", "", kPlaceholderBegin, kPlaceholderEnd,
       true},
      {"A $simple$long_v$", "A simplelong_v$", "", kPlaceholderBegin,
       kPlaceholderEnd, true},
      {"A $simple$$long_v$", "A simpleA pretty long replacement", "",
       kPlaceholderBegin, kPlaceholderEnd, true},
      {"This is $bad name$", "This is $bad name$", "", kPlaceholderBegin,
       kPlaceholderEnd, true},
      {"This is $missing$", "This is $missing$",
       "Variable $missing$ used but not defined.", kPlaceholderBegin,
       kPlaceholderEnd, false},
  });

  MessageBundle::SubstitutionMap messages;
  messages.insert(std::make_pair("simple", "simple"));
  messages.insert(std::make_pair("long", "A pretty long replacement"));
  messages.insert(std::make_pair("long_v", "A pretty long replacement"));
  messages.insert(std::make_pair("bad name", "Doesn't matter"));
  messages.insert(std::make_pair("d1g1ts_are_ok", "I are d1g1t"));

  for (const auto& entry : test_cases) {
    std::string text = entry.original;
    std::string error;
    EXPECT_EQ(entry.pass, MessageBundle::ReplaceVariables(
                              messages, entry.begin_delimiter,
                              entry.end_delimiter, &text, &error));
    EXPECT_EQ(entry.result, text);
  }
}

}  // namespace extensions
