:param str text: text to be tokenized
    :param str engine: tokenizer to be used
    :param dict custom_dict: a dictionary trie
    :param bool keep_whitespace: True to keep whitespaces, a common mark for end of phrase in Thai
    :return: list of words

    **Options for engine**
        * newmm (default) - dictionary-based, Maximum Matching + Thai Character Cluster
        * longest - dictionary-based, Longest Matching
        * deepcut - wrapper for deepcut, language-model-based https://github.com/rkcosmos/deepcut
        * icu - wrapper for ICU (International Components for Unicode, using PyICU), dictionary-based
        * ulmfit - for thai2fit
        * a custom_dict can be provided for newmm, longest, and deepcut

    **Example**
        >>> from pythainlp.tokenize import word_tokenize
        >>> text = "โอเคบ่พวกเรารักภาษาบ้านเกิด"
        >>> word_tokenize(text, engine="newmm")
        ['โอเค', 'บ่', 'พวกเรา', 'รัก', 'ภาษา', 'บ้านเกิด']
        >>> word_tokenize(text, engine="icu")
        ['โอ', 'เค', 'บ่', 'พวก', 'เรา', 'รัก', 'ภาษา', 'บ้าน', 'เกิด']

def word_tokenize(
    text: str,
    custom_dict: Trie = None,
    engine: str = "newmm",
    keep_whitespace: bool = True,
) -> List[str]:
    """
    :param str text: text to be tokenized
    :param str engine: tokenizer to be used
    :param dict custom_dict: a dictionary trie
    :param bool keep_whitespace: True to keep whitespaces, a common mark for end of phrase in Thai
    :return: list of words

    **Options for engine**
        * newmm (default) - dictionary-based, Maximum Matching + Thai Character Cluster
        * longest - dictionary-based, Longest Matching
        * deepcut - wrapper for deepcut, language-model-based https://github.com/rkcosmos/deepcut
        * icu - wrapper for ICU (International Components for Unicode, using PyICU), dictionary-based
        * ulmfit - for thai2fit
        * a custom_dict can be provided for newmm, longest, and deepcut

    **Example**
        >>> from pythainlp.tokenize import word_tokenize
        >>> text = "โอเคบ่พวกเรารักภาษาบ้านเกิด"
        >>> word_tokenize(text, engine="newmm")
        ['โอเค', 'บ่', 'พวกเรา', 'รัก', 'ภาษา', 'บ้านเกิด']
        >>> word_tokenize(text, engine="icu")
        ['โอ', 'เค', 'บ่', 'พวก', 'เรา', 'รัก', 'ภาษา', 'บ้าน', 'เกิด']
    """
    if not text or not isinstance(text, str):
        return []

    segments = []
    if engine == "newmm" or engine == "onecut":
        from .newmm import segment

        segments = segment(text, custom_dict)
    elif engine == "longest":
        from .longest import segment

        segments = segment(text, custom_dict)
    elif engine == "mm" or engine == "multi_cut":
        from .multi_cut import segment

        segments = segment(text, custom_dict)
    elif engine == "deepcut":  # deepcut can optionally use dictionary
        from .deepcut import segment

        if custom_dict:
            custom_dict = list(custom_dict)
            segments = segment(text, custom_dict)
        else:
            segments = segment(text)
    elif engine == "ulmfit":  # ulmfit has its own specific dictionary
        from .newmm import segment

        segments = segment(text, custom_dict=FROZEN_DICT_TRIE)
    elif engine == "icu":
        from .pyicu import segment

        segments = segment(text)
    else:  # default, use "newmm" engine
        from .newmm import segment

        segments = segment(text, custom_dict)

    if not keep_whitespace:
        segments = [token.strip(" ") for token in segments if token.strip(" ")]

    return segments