# Path: utils/io_utils.py
# _PAD = b"_PAD"      # Append to unused space for both encoder/decoder.
# _GO = b"_GO"       # Prepend to each decoder input.
# _EOS = b"_EOS"      # Append to outputs only. Stopping signal when decoding.
# _UNK = b"_UNK"      # For any symbols not in our vocabulary.
# _START_VOCAB = [_PAD, _GO, _EOS, _UNK]
# PAD_ID = 0
# GO_ID = 1
# EOS_ID = 2
# UNK_ID = 3
# _WORD_SPLIT = re.compile(b"([.,!?\"':;)(])")
# _DIGIT_RE = re.compile(br"\d")
# _FLAGS = Flags(pretrained_dir=None,
#                config=None,
#                debug=None,
#                model='{}',
#                dataset='{}',
#                model_params='{}',
#                dataset_params='{}')
# def save_hyper_params(hyper_params, fname):
# def get_sentence(lower=True):
# def update_config(config=None,
#                   config_path=None,
#                   return_config=True,
#                   **kwargs):
# def get_yaml_config(path, save_path=True):
# def load_pretrained_config(pretrained_dir):
# def print_non_defaults(config):
# def flags_to_dict(flags):
# def merge_dicts(default_dict, preference_dict):
# def parse_config(flags=None, pretrained_dir=None, config_path=None):
# def basic_tokenizer(sentence):
# def num_lines(file_path):
# def get_word_freqs(path, counter, norm_digits=True):
# def create_vocabulary(vocab_path, from_path, to_path, max_vocab_size, norm_digits=True):
# def get_vocab_dicts(vocabulary_path):
# def sentence_to_token_ids(sentence, vocabulary, normalize_digits=True):
# def data_to_token_ids(data_path, target_path, vocabulary_path, normalize_digits=True):
# def prepare_data(data_dir,
#                  vocab_size,
#                  from_train_path=None,
#                  to_train_path=None,
#                  from_valid_path=None,
#                  to_valid_path=None,
#                  optimize=True,
#                  config_path=None):
#     def maybe_set_param(param, file_name):
#     def get_vocab_path(vocab_size):
#     def append_to_paths(s, **paths):
# 
# Path: utils/io_utils.py
# def sentence_to_token_ids(sentence, vocabulary, normalize_digits=True):
#     """Convert a string to list of integers representing token-ids.
# 
#     For example, a sentence "I have a dog" may become tokenized into
#     ["I", "have", "a", "dog"] and with vocabulary {"I": 1, "have": 2,
#     "a": 4, "dog": 7"} this function will return [1, 2, 4, 7].
# 
#     Args:
#       sentence: the sentence in bytes format to convert to token-ids.
#       vocabulary: a dictionary mapping tokens to integers.
#       normalize_digits: Boolean; if true, all digits are replaced by 0s.
# 
#     Returns:
#       a list of integers, the token-ids for the sentence.
#     """
#     words = basic_tokenizer(sentence)
# 
#     if not normalize_digits:
#         return [vocabulary.get(w, UNK_ID) for w in words]
# 
#     # Normalize digits by 0 before looking words up in the vocabulary.
#     return [vocabulary.get(_DIGIT_RE.sub(b"0", w), UNK_ID) for w in words]
# 
# def get_vocab_dicts(vocabulary_path):
#     """Returns word_to_idx, idx_to_word dictionaries given vocabulary.
# 
#     Args:
#       vocabulary_path: path to the file containing the vocabulary.
# 
#     Returns:
#       a pair: the vocabulary (a dictionary mapping string to integers), and
#       the reversed vocabulary (a list, which reverses the vocabulary mapping).
# 
#     Raises:
#       ValueError: if the provided vocabulary_path does not exist.
#     """
#     if gfile.Exists(vocabulary_path):
#         rev_vocab = []
#         with gfile.GFile(vocabulary_path, mode="rb") as f:
#             rev_vocab.extend(f.readlines())
#         rev_vocab = [tf.compat.as_bytes(line.strip()) for line in rev_vocab]
#         vocab = dict([(x, y) for (y, x) in enumerate(rev_vocab)])
#         return vocab, rev_vocab
#     else:
#         raise ValueError("Vocabulary file %s not found.", vocabulary_path)


import tensorflow as tf
import logging
import os
import sys
import numpy as np
from utils import io_utils
from utils.io_utils import sentence_to_token_ids, get_vocab_dicts
"""Used by legacy_models for decoding. Not needed by DynamicBot."""




def decode(bot, dataset, teacher_mode=True):
    """Runs a chat session between the given chatbot and user."""

    # We decode one sentence at a time.
    bot.batch_size = 1
    # Decode from standard input.
    print("Type \"exit\" to exit.")
    print("Write stuff after the \">\" below and I, your robot friend, will respond.")
    sentence = io_utils.get_sentence()
    while sentence:
        # Convert input sentence to token-ids.
        token_ids = sentence_to_token_ids(tf.compat.as_bytes(sentence), dataset.word_to_idx)
        # Get output sentence from the chatbot.
        outputs = decode_inputs(token_ids, dataset.idx_to_word, bot)
        # Print the chatbot's response.
        print(outputs)
        if teacher_mode:
            print("What should I have said?")
            feedback = io_utils.get_sentence()

# Path: utils/io_utils.py
# _PAD = b"_PAD"      # Append to unused space for both encoder/decoder.
# _GO = b"_GO"       # Prepend to each decoder input.
# _EOS = b"_EOS"      # Append to outputs only. Stopping signal when decoding.
# _UNK = b"_UNK"      # For any symbols not in our vocabulary.
# _START_VOCAB = [_PAD, _GO, _EOS, _UNK]
# PAD_ID = 0
# GO_ID = 1
# EOS_ID = 2
# UNK_ID = 3
# _WORD_SPLIT = re.compile(b"([.,!?\"':;)(])")
# _DIGIT_RE = re.compile(br"\d")
# _FLAGS = Flags(pretrained_dir=None,
#                config=None,
#                debug=None,
#                model='{}',
#                dataset='{}',
#                model_params='{}',
#                dataset_params='{}')
# def save_hyper_params(hyper_params, fname):
# def get_sentence(lower=True):
# def update_config(config=None,
#                   config_path=None,
#                   return_config=True,
#                   **kwargs):
# def get_yaml_config(path, save_path=True):
# def load_pretrained_config(pretrained_dir):
# def print_non_defaults(config):
# def flags_to_dict(flags):
# def merge_dicts(default_dict, preference_dict):
# def parse_config(flags=None, pretrained_dir=None, config_path=None):
# def basic_tokenizer(sentence):
# def num_lines(file_path):
# def get_word_freqs(path, counter, norm_digits=True):
# def create_vocabulary(vocab_path, from_path, to_path, max_vocab_size, norm_digits=True):
# def get_vocab_dicts(vocabulary_path):
# def sentence_to_token_ids(sentence, vocabulary, normalize_digits=True):
# def data_to_token_ids(data_path, target_path, vocabulary_path, normalize_digits=True):
# def prepare_data(data_dir,
#                  vocab_size,
#                  from_train_path=None,
#                  to_train_path=None,
#                  from_valid_path=None,
#                  to_valid_path=None,
#                  optimize=True,
#                  config_path=None):
#     def maybe_set_param(param, file_name):
#     def get_vocab_path(vocab_size):
#     def append_to_paths(s, **paths):
# 
# Path: utils/io_utils.py
# def sentence_to_token_ids(sentence, vocabulary, normalize_digits=True):
#     """Convert a string to list of integers representing token-ids.
# 
#     For example, a sentence "I have a dog" may become tokenized into
#     ["I", "have", "a", "dog"] and with vocabulary {"I": 1, "have": 2,
#     "a": 4, "dog": 7"} this function will return [1, 2, 4, 7].
# 
#     Args:
#       sentence: the sentence in bytes format to convert to token-ids.
#       vocabulary: a dictionary mapping tokens to integers.
#       normalize_digits: Boolean; if true, all digits are replaced by 0s.
# 
#     Returns:
#       a list of integers, the token-ids for the sentence.
#     """
#     words = basic_tokenizer(sentence)
# 
#     if not normalize_digits:
#         return [vocabulary.get(w, UNK_ID) for w in words]
# 
#     # Normalize digits by 0 before looking words up in the vocabulary.
#     return [vocabulary.get(_DIGIT_RE.sub(b"0", w), UNK_ID) for w in words]
# 
# def get_vocab_dicts(vocabulary_path):
#     """Returns word_to_idx, idx_to_word dictionaries given vocabulary.
# 
#     Args:
#       vocabulary_path: path to the file containing the vocabulary.
# 
#     Returns:
#       a pair: the vocabulary (a dictionary mapping string to integers), and
#       the reversed vocabulary (a list, which reverses the vocabulary mapping).
# 
#     Raises:
#       ValueError: if the provided vocabulary_path does not exist.
#     """
#     if gfile.Exists(vocabulary_path):
#         rev_vocab = []
#         with gfile.GFile(vocabulary_path, mode="rb") as f:
#             rev_vocab.extend(f.readlines())
#         rev_vocab = [tf.compat.as_bytes(line.strip()) for line in rev_vocab]
#         vocab = dict([(x, y) for (y, x) in enumerate(rev_vocab)])
#         return vocab, rev_vocab
#     else:
#         raise ValueError("Vocabulary file %s not found.", vocabulary_path)


# Path: chatbot/legacy/_decode.py
import tensorflow as tf
import logging
import os
import sys
import numpy as np
from utils import io_utils
from utils.io_utils import sentence_to_token_ids, get_vocab_dicts

"""Used by legacy_models for decoding. Not needed by DynamicBot."""




def decode(bot, dataset, teacher_mode=True):
    """Runs a chat session between the given chatbot and user."""

    # We decode one sentence at a time.
    bot.batch_size = 1
    # Decode from standard input.
    print("Type \"exit\" to exit.")
    print("Write stuff after the \">\" below and I, your robot friend, will respond.")
    sentence = io_utils.get_sentence()
    while sentence:
        # Convert input sentence to token-ids.
        token_ids = sentence_to_token_ids(tf.compat.as_bytes(sentence), dataset.word_to_idx)
        # Get output sentence from the chatbot.
        outputs = decode_inputs(token_ids, dataset.idx_to_word, bot)
        # Print the chatbot's response.
        print(outputs)
        if teacher_mode:
            print("What should I have said?")
            feedback = io_utils.get_sentence()

            feedback_ids = sentence_to_token_ids(tf.compat.as_bytes(feedback), dataset.inputs_to_word)