<commit_before><?php

namespace Plancke\HypixelPHP\cache\impl\mongo;

use MongoDB\Client;
use Plancke\HypixelPHP\cache\CacheHandler;
use Plancke\HypixelPHP\cache\CacheTimes;
use Plancke\HypixelPHP\classes\HypixelObject;
use Plancke\HypixelPHP\HypixelPHP;
use Plancke\HypixelPHP\responses\booster\Boosters;
use Plancke\HypixelPHP\responses\friend\Friends;
use Plancke\HypixelPHP\responses\guild\Guild;
use Plancke\HypixelPHP\responses\KeyInfo;
use Plancke\HypixelPHP\responses\Leaderboards;
use Plancke\HypixelPHP\responses\player\Player;
use Plancke\HypixelPHP\responses\Session;
use Plancke\HypixelPHP\responses\WatchdogStats;

/**
 * Implementation for CacheHandler, stores data in MongoDB
 *
 * Class MongoCacheHandler
 * @package HypixelPHP
 */
class MongoCacheHandler extends CacheHandler {

    protected $mongoClient;

    public function __construct(HypixelPHP $HypixelPHP, Client $mongoClient) {
        parent::__construct($HypixelPHP);

        $this->mongoClient = $mongoClient;
    }

    /**
     * Use this to construct your mongo client,
     * ensures the returned values are of the php array type
     *
     * Should be added as the 'typeMap' field in $driverOptions
     *
     * @return array
     */
    public static function getTypeMap() {
        return [
            'root' => 'array',
            'document' => 'array',
            'array' => 'array'
        ];
    }

    /**
     * Run this code once to initialize the indexes on the collections
     *
     * I'm not entirely sure how performant making this call every time is so I'm not taking any chances
     */
    public function ensureIndexes() {
        $db = $this->selectDB();

        $db->selectCollection(CollectionNames::API_KEYS)->createIndex(['record.key' => 1], ['background' => true]);

        $db->selectCollection(CollectionNames::PLAYERS)->createIndex(['record.uuid' => 1], ['background' => true]);
        $db->selectCollection(CollectionNames::PLAYERS)->createIndex(['record.playername' => 1], ['background' => true]);
        $db->selectCollection(CollectionNames::PLAYER_UUID)->createIndex(['name_lowercase' => 1], ['background' => true]);

        $db->selectCollection(CollectionNames::GUILDS)->createIndex(['record._id' => 1], ['background' => true]);
        $db->selectCollection(CollectionNames::GUILDS)->createIndex(['extra.name_lower' => 1], ['background' => true]);
        $db->selectCollection(CollectionNames::GUILDS_UUID)->createIndex(['uuid' => 1], ['background' => true]);
        $db->selectCollection(CollectionNames::GUILDS_NAME)->createIndex(['name_lower' => 1], ['background' => true]);

        $db->selectCollection(CollectionNames::FRIENDS)->createIndex(['record.uuid' => 1], ['background' => true]);

        $db->selectCollection(CollectionNames::SESSIONS)->createIndex(['record.uuid' => 1], ['background' => true]);

        $db->selectCollection(CollectionNames::SINGLE_SAVE)->createIndex(['key' => 1], ['background' => true]);

        return $this;
    }

    /**
     * @return \MongoDB\Database
     */
    public function selectDB() {
        return $this->mongoClient->selectDatabase("HypixelPHP");
    }

    /**
     * @param $collection
     * @param $query
     * @param $obj
     */
    public function updateCollection($collection, $query, $obj) {
        if ($obj instanceof HypixelObject) {
            $this->selectDB()->selectCollection($collection)->replaceOne($query, $obj->getRaw(), ['upsert' => true]);
        } else {
            $this->selectDB()->selectCollection($collection)->replaceOne($query, $obj, ['upsert' => true]);
        }
    }

    /**
     * @param $collection
     * @param $query
     * @return array|null
     */
    public function queryCollection($collection, $query) {
        /** @noinspection PhpUndefinedFieldInspection */
        return $this->selectDB()->selectCollection($collection)->findOne($query);
    }

    /**
     * @param $key
     * @param HypixelObject $hypixelObject
     */
    function setSingleSave($key, HypixelObject $hypixelObject) {
        $query = ['key' => $key];

        $raw = $hypixelObject->getRaw();
        $raw['key'] = $key;

        $this->updateCollection(CollectionNames::SINGLE_SAVE, $query, $raw);
    }

    /**
     * @param $key
     * @param $constructor
     * @return HypixelObject|null
     */<commit_msg>set the typemap in the query<commit_after><?php

namespace Plancke\HypixelPHP\cache\impl\mongo;

use MongoDB\Client;
use Plancke\HypixelPHP\cache\CacheHandler;
use Plancke\HypixelPHP\cache\CacheTimes;
use Plancke\HypixelPHP\classes\HypixelObject;
use Plancke\HypixelPHP\HypixelPHP;
use Plancke\HypixelPHP\responses\booster\Boosters;
use Plancke\HypixelPHP\responses\friend\Friends;
use Plancke\HypixelPHP\responses\guild\Guild;
use Plancke\HypixelPHP\responses\KeyInfo;
use Plancke\HypixelPHP\responses\Leaderboards;
use Plancke\HypixelPHP\responses\player\Player;
use Plancke\HypixelPHP\responses\Session;
use Plancke\HypixelPHP\responses\WatchdogStats;

/**
 * Implementation for CacheHandler, stores data in MongoDB
 *
 * Class MongoCacheHandler
 * @package HypixelPHP
 */
class MongoCacheHandler extends CacheHandler {

    protected $mongoClient;

    public function __construct(HypixelPHP $HypixelPHP, Client $mongoClient) {
        parent::__construct($HypixelPHP);

        $this->mongoClient = $mongoClient;
    }

    /**
     * Run this code once to initialize the indexes on the collections
     *
     * I'm not entirely sure how performant making this call every time is so I'm not taking any chances
     */
    public function ensureIndexes() {
        $db = $this->selectDB();

        $db->selectCollection(CollectionNames::API_KEYS)->createIndex(['record.key' => 1], ['background' => true]);

        $db->selectCollection(CollectionNames::PLAYERS)->createIndex(['record.uuid' => 1], ['background' => true]);
        $db->selectCollection(CollectionNames::PLAYERS)->createIndex(['record.playername' => 1], ['background' => true]);
        $db->selectCollection(CollectionNames::PLAYER_UUID)->createIndex(['name_lowercase' => 1], ['background' => true]);

        $db->selectCollection(CollectionNames::GUILDS)->createIndex(['record._id' => 1], ['background' => true]);
        $db->selectCollection(CollectionNames::GUILDS)->createIndex(['extra.name_lower' => 1], ['background' => true]);
        $db->selectCollection(CollectionNames::GUILDS_UUID)->createIndex(['uuid' => 1], ['background' => true]);
        $db->selectCollection(CollectionNames::GUILDS_NAME)->createIndex(['name_lower' => 1], ['background' => true]);

        $db->selectCollection(CollectionNames::FRIENDS)->createIndex(['record.uuid' => 1], ['background' => true]);

        $db->selectCollection(CollectionNames::SESSIONS)->createIndex(['record.uuid' => 1], ['background' => true]);

        $db->selectCollection(CollectionNames::SINGLE_SAVE)->createIndex(['key' => 1], ['background' => true]);

        return $this;
    }

    /**
     * @return \MongoDB\Database
     */
    public function selectDB() {
        return $this->mongoClient->selectDatabase("HypixelPHP");
    }

    /**
     * @param $collection
     * @param $query
     * @param $obj
     */
    public function updateCollection($collection, $query, $obj) {
        if ($obj instanceof HypixelObject) {
            $this->selectDB()->selectCollection($collection)->replaceOne($query, $obj->getRaw(), ['upsert' => true]);
        } else {
            $this->selectDB()->selectCollection($collection)->replaceOne($query, $obj, ['upsert' => true]);
        }
    }

    /**
     * @param $collection
     * @param $query
     * @return array|null
     */
    public function queryCollection($collection, $query) {
        /** @noinspection PhpUndefinedFieldInspection */
        return $this->selectDB()->selectCollection($collection)->findOne($query, [
            'typeMap' => [
                'root' => 'array',
                'document' => 'array',
                'array' => 'array'
            ]
        ]);
    }

    /**
     * @param $key
     * @param HypixelObject $hypixelObject
     */
    function setSingleSave($key, HypixelObject $hypixelObject) {
        $query = ['key' => $key];

        $raw = $hypixelObject->getRaw();
        $raw['key'] = $key;

        $this->updateCollection(CollectionNames::SINGLE_SAVE, $query, $raw);
    }

    /**
     * @param $key
     * @param $constructor
     * @return HypixelObject|null
     */
{'fraction_non_alphanumeric': 0.15592417061611374, 'fraction_numerical': 0.0026066350710900474, 'mean_word_length': 3.430971128608924, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 136, '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': '965875', 'n_tokens_mistral': 2564, 'n_tokens_neox': 2442, 'n_words': 461}