<commit_before>// Copyright (c) 2019 <NAME>, <NAME>, <NAME>

// We are making my contributions/submissions to this project solely in our
// personal capacity and are not conveying any rights to any intellectual
// property of any third parties.

#include "Console.hpp"

#include <Rosetta/Cards/Card.hpp>
#include <Rosetta/Cards/Cards.hpp>
#include <Rosetta/Commons/Constants.hpp>
#include <Rosetta/Commons/Macros.hpp>
#include <Rosetta/Commons/Utils.hpp>
#include <Rosetta/Games/Game.hpp>
#include <Rosetta/Loaders/AccountLoader.hpp>
#include <Rosetta/Loaders/CardLoader.hpp>
#include <Rosetta/Policies/IoPolicy.hpp>

#include <cctype>
#if defined(ROSETTASTONE_WINDOWS)
#include <filesystem>
#elif defined(ROSETTASTONE_LINUX)
#include <experimental/filesystem>
#elif defined(ROSETTASTONE_MACOSX)
#include <sys/stat.h>
#endif
#include <fstream>
#include <iomanip>
#include <iostream>

#if defined(ROSETTASTONE_WINDOWS)
namespace filesystem = std::filesystem;
#elif defined(ROSETTASTONE_LINUX)
namespace filesystem = std::experimental::filesystem;
#endif

namespace RosettaStone
{
void Console::SignIn()
{
    std::cout << "Input Account ID to load data.\n";
    std::cout << "If you do not want to load, please input \"STOP\"\n";

    while (true)
    {
        std::cout << "Account ID: ";
        std::string accountID;
        std::cin >> accountID;

        if (accountID == "STOP")
        {
            break;
        }

#ifndef ROSETTASTONE_MACOSX
        if (!filesystem::exists("Datas/" + accountID + ".json"))
#else
        struct stat buf;
        std::string path = "Datas/" + accountID + ".json";
        if (stat(path.c_str(), &buf) == -1)
#endif
        {
            std::cout << accountID << ".json doesn't exist. Try again.\n";
            continue;
        }

        AccountLoader loader;
        m_account = loader.Load(accountID);

        if (m_account == nullptr)
        {
            std::cout << "An error occurred while loading account data.\n";
            continue;
        }

        std::cout << "You are signed in. Hello, " << accountID << "!\n";

        Main();

        break;
    }
}

void Console::SignUp()
{
    std::cout << "Input Account ID to create data.\n";

    while (true)
    {
        std::cout << "Account ID: ";
        std::string accountID;
        std::cin >> accountID;

#if defined(ROSETTASTONE_WINDOWS) || defined(ROSETTASTONE_LINUX)
        if (filesystem::exists("Datas/" + accountID + ".json"))
#elif defined(ROSETTASTONE_MACOSX)
        struct stat buf;
        std::string path = "Datas/" + accountID + ".json";
        if (stat(path.c_str(), &buf) == 0)
#endif
        {
            std::cout << accountID << ".json already exists. Try again.\n";
            continue;
        }

        std::cout << "Name: ";
        std::string name;
        std::cin >> name;

        m_account = new AccountInfo(std::move(accountID), std::move(name));

        AccountLoader loader;
        loader.Save(m_account);

        std::cout << "Your account has been created. Please sign in.\n";
        break;
    }
}

std::optional<Card> Console::SearchCard() const
{
    std::cout << "========================================\n";
    std::cout << "              Search Card!              \n";
    std::cout << "========================================\n";

    // Extracts and discards characters from the input stream.
    std::cin.ignore();

    std::cout << "If you want to get help, type -h or --help.\n";

    while (true)
    {
        auto [filter, isValid, isFinish] =
            InputAndParseSearchCommand("Command > ");

        if (!isValid)
        {
            continue;
        }

        if (isFinish)
        {
            break;
        }

        std::cout << "========================================\n";
        std::cout << "             Search Result!             \n";
        std::cout << "========================================\n";

        std::vector<Card> result = ProcessSearchCommand(filter);
        if (result.empty())
        {
            std::cout << "There are no cards matching your search condition.\n";
        }
        else
        {
            size_t cardIdx = 1;

            for (auto& card : result)
            {
                std::cout << cardIdx << ". ";
                card.ShowBriefInfo();
                std::cout << '\n';

                cardIdx++;
            }

            if (m_searchMode == SearchMode::AddCardInDeck)
            {
                const size_t selectedCardIndex =
                    InputMenuNum("Select: ", cardIdx);
                return result.at(selectedCardIndex);
            }
        }
    }

    return {};
}

int Console::ManageDeck()
{
    std::cout << "========================================\n";
    std::cout << "              Manage Deck!              \n";
    std::cout << "========================================\n";

    ShowMenu(m_manageDeckStr);
    const size_t selectedNum = InputMenuNum("Select: ", MANAGE_DECK_MENU_SIZE);
    bool isFinish = false;

    if (selectedNum != MANAGE_DECK_MENU_SIZE)
    {
        m_manageDeckFuncs[selectedNum - 1](*this);
    }
    else
    {
        isFinish = true;
    }

    return isFinish ? 0 : ManageDeck();
}

void Console::SimulateGame() const<commit_msg>fix: Correct vector index error to cause crash problem<commit_after>// Copyright (c) 2019 <NAME>, <NAME>, <NAME>

// We are making my contributions/submissions to this project solely in our
// personal capacity and are not conveying any rights to any intellectual
// property of any third parties.

#include "Console.hpp"

#include <Rosetta/Cards/Card.hpp>
#include <Rosetta/Cards/Cards.hpp>
#include <Rosetta/Commons/Constants.hpp>
#include <Rosetta/Commons/Macros.hpp>
#include <Rosetta/Commons/Utils.hpp>
#include <Rosetta/Games/Game.hpp>
#include <Rosetta/Loaders/AccountLoader.hpp>
#include <Rosetta/Loaders/CardLoader.hpp>
#include <Rosetta/Policies/IoPolicy.hpp>

#include <cctype>
#if defined(ROSETTASTONE_WINDOWS)
#include <filesystem>
#elif defined(ROSETTASTONE_LINUX)
#include <experimental/filesystem>
#elif defined(ROSETTASTONE_MACOSX)
#include <sys/stat.h>
#endif
#include <fstream>
#include <iomanip>
#include <iostream>

#if defined(ROSETTASTONE_WINDOWS)
namespace filesystem = std::filesystem;
#elif defined(ROSETTASTONE_LINUX)
namespace filesystem = std::experimental::filesystem;
#endif

namespace RosettaStone
{
void Console::SignIn()
{
    std::cout << "Input Account ID to load data.\n";
    std::cout << "If you do not want to load, please input \"STOP\"\n";

    while (true)
    {
        std::cout << "Account ID: ";
        std::string accountID;
        std::cin >> accountID;

        if (accountID == "STOP")
        {
            break;
        }

#ifndef ROSETTASTONE_MACOSX
        if (!filesystem::exists("Datas/" + accountID + ".json"))
#else
        struct stat buf;
        std::string path = "Datas/" + accountID + ".json";
        if (stat(path.c_str(), &buf) == -1)
#endif
        {
            std::cout << accountID << ".json doesn't exist. Try again.\n";
            continue;
        }

        AccountLoader loader;
        m_account = loader.Load(accountID);

        if (m_account == nullptr)
        {
            std::cout << "An error occurred while loading account data.\n";
            continue;
        }

        std::cout << "You are signed in. Hello, " << accountID << "!\n";

        Main();

        break;
    }
}

void Console::SignUp()
{
    std::cout << "Input Account ID to create data.\n";

    while (true)
    {
        std::cout << "Account ID: ";
        std::string accountID;
        std::cin >> accountID;

#if defined(ROSETTASTONE_WINDOWS) || defined(ROSETTASTONE_LINUX)
        if (filesystem::exists("Datas/" + accountID + ".json"))
#elif defined(ROSETTASTONE_MACOSX)
        struct stat buf;
        std::string path = "Datas/" + accountID + ".json";
        if (stat(path.c_str(), &buf) == 0)
#endif
        {
            std::cout << accountID << ".json already exists. Try again.\n";
            continue;
        }

        std::cout << "Name: ";
        std::string name;
        std::cin >> name;

        m_account = new AccountInfo(std::move(accountID), std::move(name));

        AccountLoader loader;
        loader.Save(m_account);

        std::cout << "Your account has been created. Please sign in.\n";
        break;
    }
}

std::optional<Card> Console::SearchCard() const
{
    std::cout << "========================================\n";
    std::cout << "              Search Card!              \n";
    std::cout << "========================================\n";

    // Extracts and discards characters from the input stream.
    std::cin.ignore();

    std::cout << "If you want to get help, type -h or --help.\n";

    while (true)
    {
        auto [filter, isValid, isFinish] =
            InputAndParseSearchCommand("Command > ");

        if (!isValid)
        {
            continue;
        }

        if (isFinish)
        {
            break;
        }

        std::cout << "========================================\n";
        std::cout << "             Search Result!             \n";
        std::cout << "========================================\n";

        std::vector<Card> result = ProcessSearchCommand(filter);
        if (result.empty())
        {
            std::cout << "There are no cards matching your search condition.\n";
        }
        else
        {
            size_t cardIdx = 1;

            for (auto& card : result)
            {
                std::cout << cardIdx << ". ";
                card.ShowBriefInfo();
                std::cout << '\n';

                cardIdx++;
            }

            if (m_searchMode == SearchMode::AddCardInDeck)
            {
                const size_t selectedCardIndex =
                    InputMenuNum("Select: ", cardIdx);
                return result.at(selectedCardIndex - 1);
            }
        }
    }

    return {};
}

int Console::ManageDeck()
{
    std::cout << "========================================\n";
    std::cout << "              Manage Deck!              \n";
    std::cout << "========================================\n";

    ShowMenu(m_manageDeckStr);
    const size_t selectedNum = InputMenuNum("Select: ", MANAGE_DECK_MENU_SIZE);
    bool isFinish = false;

    if (selectedNum != MANAGE_DECK_MENU_SIZE)
    {
        m_manageDeckFuncs[selectedNum - 1](*this);
    }
    else
    {
        isFinish = true;
    }

    return isFinish ? 0 : ManageDeck();
}

void Console::SimulateGame() const
{'fraction_non_alphanumeric': 0.17802635320883495, 'fraction_numerical': 0.0018011185894397574, 'mean_word_length': 2.2541640962368907, 'pattern_counts': {'":': 0, '<': 161, '<?xml version=': 0, '>': 59, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7470384', 'n_tokens_mistral': 3234, 'n_tokens_neox': 3085, 'n_words': 750}