#include "word_list.h"

#include <algorithm>
#include <cmath>
#include <fstream>
#include <initializer_list>
#include <random>

WordList &WordList::multiply(size_t factor) {
  WordList result;
  result.reserve(size() * factor);

  for (auto time = 0; time < factor; ++time) {
    std::copy(cbegin(), cend(), std::back_inserter(result));
  }

  std::swap(*this, result);

  return *this;
};

WordList &WordList::shuffle() {
  std::random_device random_device;
  std::mt19937 random_number_generator(random_device());
  std::shuffle(begin(), end(), random_number_generator);

  return *this;
}

WordList WordList::oneCap() {
  const static std::string charset = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";

  WordList word_list;
  word_list.reserve(charset.length());

  for (const auto char_1 : charset) {
    word_list.emplace_back(std::initializer_list<char>({char_1}));
  }

  return word_list;
};

WordList WordList::fourCaps() {
  const static std::string charset = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";

  WordList word_list;
  word_list.reserve(std::pow(charset.length(), 4));

  for (const auto char_1 : charset) {
    for (const auto char_2 : charset) {
      for (const auto char_3 : charset) {
        for (const auto char_4 : charset) {
          word_list.emplace_back(
              std::initializer_list<char>({char_1, char_2, char_3, char_4}));
        }
      }
    }
  }

  return word_list;
};

WordList WordList::fromFile(const std::filesystem::path &path) {
  WordList word_list;

  std::ifstream ifs(path);

  std::string line;
  while (std::getline(ifs, line)) {
    word_list.emplace_back(line);
  }

  return word_list;
}

WordRefList::WordRefList(const WordList &source) {
  for (const auto &word : source) {
    push_back(&word);
  }
}
