<?php
// Rewrite this script when everything has proper objects associated with it and use those objects

require_once __DIR__ . '/../misuzu.php';

if(!MSZ_DEBUG)
    die('Not running in debug mode. Are you sure you want to run this?' . PHP_EOL);

require_once __DIR__ . '/sample/MarkovDictionary.php';

define('MKV_DICTS', __DIR__ . '/sample/dicts');
define('MKV_PASSWD', '123456');
define('MKV_MAIL', 'msz-%d@flash.moe');
define('MKV_ALPHA', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ');
define('MKV_ALPHA_LEN', strlen(MKV_ALPHA));

function mkv_log(string $string): void {
    printf('[%s] %s%s', date('H:i:s'), $string, PHP_EOL);
}

mkv_log('Filling database with markov data...');

mkv_log('Yoinked Database instance from Misuzu...');
$db = \Misuzu\DB::getInstance();

mkv_log('Opening role dictionaries...');
$roleNames = new MarkovDictionary(MKV_DICTS . '/roles_names.fmk');
$roleDescs = new MarkovDictionary(MKV_DICTS . '/roles_descs.fmk');
$roleTitles = new MarkovDictionary(MKV_DICTS . '/roles_titles.fmk');

mkv_log('Nuking roles table...');
$db->exec('DELETE FROM `msz_roles` WHERE `role_id` > 1');
$db->exec('ALTER TABLE `msz_roles` AUTO_INCREMENT = 2');

mkv_log('Running slow cron to ensure main role exists...');

// running cron before fuckery
(new \Misuzu\Console\Commands\CronCommand)->dispatch(
    new \Misuzu\Console\CommandArgs(['--slow'])
);

mkv_log('Preparing role and permissions insert statements...');
$cr = $db->prepare('INSERT INTO `msz_roles` (`role_hierarchy`, `role_name`, `role_title`, `role_description`, `role_hidden`, `role_can_leave`, `role_colour`) VALUES (:rank, :name, :title, :desc, :hide, :leave, :colour)');
$cp = $db->prepare('REPLACE INTO `msz_permissions` (`role_id`, `general_perms_allow`, `user_perms_allow`, `changelog_perms_allow`, `news_perms_allow`, `forum_perms_allow`, `comments_perms_allow`) VALUES (:role, :general, :user, :changelog, :news, :forum, :comments)');

mkv_log('Adding permissions for main role...');
$cp->bind('role', 1);
$cp->bind('general', 0);
$cp->bind('user', 59);
$cp->bind('changelog', 0);
$cp->bind('news', 0);
$cp->bind('forum', 0);
$cp->bind('comments', 137);
$cp->execute();

mkv_log('Creating Global Moderator role...');
$cr->bind('rank', 5);
$cr->bind('name', 'Global Moderator');
$cr->bind('title', 'Moderator');
$cr->bind('desc', 'They are global and in moderation.');
$cr->bind('hide', 0);
$cr->bind('leave', 0);
$cr->bind('colour', 1693465);
$cr->execute();

mkv_log('Adding permissions for Global Moderator...');
$cp->bind('role', $rIdMod = $db->lastId());
$cp->bind('general', 3);
$cp->bind('user', 25165887);
$cp->bind('changelog', 0);
$cp->bind('news', 0);
$cp->bind('forum', 0);
$cp->bind('comments', 57);
$cp->execute();

mkv_log('Creating Administrator role...');
$cr->bind('rank', 10);
$cr->bind('name', 'Administrator');
$cr->bind('title', 'Administrator');
$cr->bind('desc', 'Administration nation.');
$cr->bind('hide', 0);
$cr->bind('leave', 0);
$cr->bind('colour', 16711680);
$cr->execute();

mkv_log('Adding permissions for Administrator...');
$cp->bind('role', $rIdAdm = $db->lastId());
$cp->bind('general', 39);
$cp->bind('user', 28311615);
$cp->bind('changelog', 3);
$cp->bind('news', 3);
$cp->bind('forum', 3);
$cp->bind('comments', 249);
$cp->execute();

mkv_log('Creating Bot role...');
$cr->bind('rank', 7);
$cr->bind('name', 'Bot');
$cr->bind('title', null);
$cr->bind('desc', 'Service users.');
$cr->bind('hide', 0);
$cr->bind('leave', 0);
$cr->bind('colour', 10390951);
$cr->execute();

$rIdBot = $db->lastId();

mkv_log('Creating Tester role...');
$cr->bind('rank', 1);
$cr->bind('name', 'Tester');
$cr->bind('title', null);
$cr->bind('desc', 'Experimentalists.');
$cr->bind('hide', 1);
$cr->bind('leave', 1);
$cr->bind('colour', 1073741824);
$cr->execute();

mkv_log('Adding permissions for Tester...');
$cp->bind('role', $rIdTest = $db->lastId());
$cp->bind('general', 16);
$cp->bind('user', 0);
$cp->bind('changelog', 3);
$cp->bind('news', 0);
$cp->bind('forum', 0);
$cp->bind('comments', 0);
$cp->execute();

mkv_log('Creating OG role...');
$cr->bind('rank', 1);
$cr->bind('name', 'OG');
$cr->bind('title', null);
$cr->bind('desc', 'Arbitrarily selected people that joined in 2013 and 2014.');
$cr->bind('hide', 0);
$cr->bind('leave', 0);
$cr->bind('colour', 15740285);
$cr->execute();

mkv_log('Creating Developer role...');
$cr->bind('rank', 5);
$cr->bind('name', 'Developer');
$cr->bind('title', 'Developer');
$cr->bind('desc', 'Moderators but without the requirement to moderate.');
$cr->bind('hide', 0);
$cr->bind('leave', 0);
$cr->bind('colour', 7558084);
$cr->execute();

mkv_log('Adding permissions for Developer...');
$cp->bind('role', $rIdDev = $db->lastId());
$cp->bind('general', 3);
$cp->bind('user', 25165887);
$cp->bind('changelog', 3);
$cp->bind('news', 0);
$cp->bind('forum', 0);
$cp->bind('comments', 57);
$cp->execute();

mkv_log('Creating Tenshi role...');
$cr->bind('rank', 1);
$cr->bind('name', 'Tenshi');
$cr->bind('title', 'Supporter');
$cr->bind('desc', 'Donators');
$cr->bind('hide', 0);
$cr->bind('leave', 0);
$cr->bind('colour', 15635456);
$cr->execute();

mkv_log('Adding permissions for Tenshi...');
$cp->bind('role', $rIdTen = $db->lastId());
$cp->bind('general', 0);
$cp->bind('user', 4);
$cp->bind('changelog', 0);
$cp->bind('news', 0);
$cp->bind('forum', 0);
$cp->bind('comments', 0);
$cp->execute();

for($i = 0; $i < 10; ++$i) {
    mkv_log('Creating bogus role ' . $i . '...');
    $cr->bind('rank', mt_rand(1, 4));
    $cr->bind('name', $roleNames->generate());
    $cr->bind('title', (mt_rand(0, 100) > 50) ? $roleTitles->generate() : null);
    $cr->bind('desc', (mt_rand(0, 100) > 10) ? $roleDescs->generate() : null);
    $cr->bind('hide', mt_rand(0, 1));
    $cr->bind('leave', mt_rand(0, 1));
    $cr->bind('colour', ((mt_rand(0, 255) << 16) | (mt_rand(0, 255) << 8) | mt_rand(0, 255)));
    $cr->execute();
}

mkv_log('Opening user related markov dictionaries...');
$userNames = new MarkovDictionary(MKV_DICTS . '/users_names.fmk');
$userTitles = new MarkovDictionary(MKV_DICTS . '/users_titles.fmk');
$userSigs = new MarkovDictionary(MKV_DICTS . '/users_sigs.fmk');
$userAbouts = new MarkovDictionary(MKV_DICTS . '/users_abouts.fmk');

mkv_log('Nuking users table...');
$db->exec('DELETE FROM `msz_users`');
$db->exec('ALTER TABLE `msz_users` AUTO_INCREMENT = 1');

mkv_log('Preparing user insert statements...');
$cu = $db->prepare('INSERT INTO `msz_users` (`username`, `password`, `email`, `register_ip`, `last_ip`, `user_super`, `user_country`, `user_about_content`, `user_about_parser`, `user_signature_content`, `user_signature_parser`, `user_birthdate`, `user_title`, `display_role`) VALUES (:name, :pass, :mail, :reg_addr, :last_addr, :super, :country, :about_text, :about_parse, :sig_text, :sig_parse, :birth, :title, :role)');

$ur = $db->prepare('REPLACE INTO `msz_user_roles` (`user_id`, `role_id`) VALUES (:user, :role)');

mkv_log('Creating admin user...');
mkv_log('NOTICE: All passwords will be set to: ' . MKV_PASSWD);
mkv_log('NOTICE: E-mail address will follow the format of: ' . MKV_MAIL);
$cu->bind('name', 'admin');
$cu->bind('pass', password_hash(MKV_PASSWD, PASSWORD_ARGON2ID));
$cu->bind('mail', sprintf(MKV_MAIL, 1));
$cu->bind('reg_addr', "\x7f\0\0\1");
$cu->bind('last_addr', "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\1");
$cu->bind('super', 1);
$cu->bind('country', 'NL');
$cu->bind('about_text', '# Default administrator account');
$cu->bind('about_parse', 2);
$cu->bind('sig_text', '[b]Administrative Signature[/b]');
$cu->bind('sig_parse', 1);
$cu->bind('birth', '2013-01-27');
$cu->bind('title', null);
$cu->bind('role', 3);
$cu->execute();

mkv_log('Adding Global Moderator role to admin...');
$ur->bind('user', 1);
$ur->bind('role', 2);
$ur->execute();

mkv_log('Adding Administrator role to admin...');
$ur->bind('user', 1);
$ur->bind('role', 3);
$ur->execute();

mkv_log('Adding Developer role to admin...');
$ur->bind('user', 1);
$ur->bind('role', 8);
$ur->execute();

$cu->bind('super', 0);

for($i = 1; $i < 2000; ++$i) {
    mkv_log('Creating bogus user ' . $i . '...');
    $cu->bind('name', mb_substr($userNames->generate(), 0, 200, 'utf-8') . $i);
    $cu->bind('pass', password_hash(MKV_PASSWD, PASSWORD_ARGON2ID));
    $cu->bind('mail', sprintf(MKV_MAIL, ($i + 1)));
    $cu->bind('reg_addr', random_bytes(mt_rand(0, 1) ? 4 : 16));
    $cu->bind('last_addr', random_bytes(mt_rand(0, 1) ? 4 : 16));
    $cu->bind('country', MKV_ALPHA[mt_rand(0, MKV_ALPHA_LEN - 1)] . MKV_ALPHA[mt_rand(0, MKV_ALPHA_LEN - 1)]);
    $cu->bind('about_text', mb_substr($userAbouts->generate(), 0, 60000, 'utf-8'));
    $cu->bind('about_parse', mt_rand(0, 2));
    $cu->bind('sig_text', mb_substr($userSigs->generate(), 0, 1000, 'utf-8'));
    $cu->bind('sig_parse', mt_rand(0, 2));
    $cu->bind('birth', date('Y-m-d', mt_rand(1, 0x7FFFFFFF)));
    $cu->bind('title', mt_rand(0, 100) > 90 ? mb_substr($userTitles->generate(), 0, 64, 'utf-8') : null);
    $cu->bind('role', mt_rand(9, 18));
    $cu->execute();

    $uId = $db->lastId();

    for($j = 0; $j < mt_rand(1, 4); ++$j) {
        $brid = mt_rand(9, 18);
        mkv_log('Adding role ' . $brid . ' to bogus user id ' . $uId . '...');
        $ur->bind('user', $uId);
        $ur->bind('role', $brid);
        $ur->execute();
    }
}

mkv_log('Opening changelog tag markov dictionaries...');
$changeTagsNames = new MarkovDictionary(MKV_DICTS . '/changes_tags_names.fmk');
$changeTagsDescs = new MarkovDictionary(MKV_DICTS . '/changes_tags_descs.fmk');

mkv_log('Nuking changelog tags table...');
$db->exec('DELETE FROM `msz_changelog_tags`');
$db->exec('ALTER TABLE `msz_changelog_tags` AUTO_INCREMENT = 1');

mkv_log('Preparing changelog insert statements...');
$ct = $db->prepare('INSERT INTO `msz_changelog_tags` (`tag_name`, `tag_description`) VALUES (:name, :descr)');
$cTagIds = [];

for($i = 0; $i < 20; ++$i) {
    mkv_log('Inserting bogus changelog tag...');
    $ct->bind('name', mb_substr($changeTagsNames->generate(), 0, 200, 'utf-8') . $i);
    $ct->bind('descr', mb_substr($changeTagsDescs->generate(), 0, 60000, 'utf-8'));
    $ct->execute();
    $cTagIds[] = $db->lastId();
}

mkv_log('Opening changelog changes markov dictionaries...');
$changeLogs = new MarkovDictionary(MKV_DICTS . '/changes_logs.fmk');
$changeTexts = new MarkovDictionary(MKV_DICTS . '/changes_texts.fmk');

mkv_log('Nuking changelog changes tables...');
$db->exec('DELETE FROM `msz_changelog_changes`');
$db->exec('ALTER TABLE `msz_changelog_changes` AUTO_INCREMENT = 1');

mkv_log('Preparing changelog changes statements...');
$cc = $db->prepare('INSERT INTO `msz_changelog_changes` (`user_id`, `change_action`, `change_created`, `change_log`, `change_text`) VALUES (:user, :action, FROM_UNIXTIME(:created), :log, :text)');
$ctt = $db->prepare('REPLACE INTO `msz_changelog_change_tags` (`change_id`, `tag_id`) VALUES (:change, :tag)');

$max = mt_rand(1000, 10000);
mkv_log('Inserting ' . $max . ' changelog entries...');
for($i = 0; $i < $max; ++$i) {
    mkv_log('Inserting bogus change ' . $i . '...');
    $userId = mt_rand(-100, 2000);
    if($userId < 1)
        $userId = null;
    $cc->bind('user', $userId);
    $cc->bind('action', mt_rand(0, 6));
    $cc->bind('created', mt_rand(1, 0x7FFFFFFF));
    $cc->bind('log', mb_substr($changeLogs->generate(), 0, 240, 'utf-8'));
    $cc->bind('text', mt_rand(0, 100) > 90 ? mb_substr($changeTexts->generate(), 0, 60000, 'utf-8') : null);
    $cc->execute();

    $ctt->bind('change', $db->lastId());

    for($j = 0; $j < mt_rand(1, 5); ++$j) {
        $btag = $cTagIds[array_rand($cTagIds)];
        mkv_log('Adding tag ' . $btag . ' to bogus change ' . $i . '...');
        $ctt->bind('tag', $btag);
        $ctt->execute();
    }
}

mkv_log('Opening news category markov dictionaries...');
$newsCatsNames = new MarkovDictionary(MKV_DICTS . '/news_cats_names.fmk');
$newsCatsDescs = new MarkovDictionary(MKV_DICTS . '/news_cats_descs.fmk');

mkv_log('Nuking news categories table...');
$db->exec('DELETE FROM `msz_news_categories`');
$db->exec('ALTER TABLE `msz_news_categories` AUTO_INCREMENT = 1');

mkv_log('Preparing news categories insert statements...');
$nc = $db->prepare('INSERT INTO `msz_news_categories` (`category_name`, `category_description`, `category_is_hidden`) VALUES (:name, :descr, :hidden)');
$ncIds = [];

for($i = 0; $i < 10; ++$i) {
    mkv_log('Creating bogus news category ' . $i . '...');
    $nc->bind('name', mb_substr($newsCatsNames->generate(), 0, 200, 'utf-8'));
    $nc->bind('descr', mb_substr($newsCatsDescs->generate(), 0, 60000, 'utf-8'));
    $nc->bind('hidden', mt_rand(0, 1));
    $nc->execute();
    $ncIds[] = $db->lastId();
}

mkv_log('Opening news post markov dictionaries...');
$newsPostsTitles = new MarkovDictionary(MKV_DICTS . '/news_posts_titles.fmk');
$newsPostsTexts = new MarkovDictionary(MKV_DICTS . '/news_posts_texts.fmk');

mkv_log('Nuking news posts table...');
$db->exec('DELETE FROM `msz_news_posts`');
$db->exec('ALTER TABLE `msz_news_posts` AUTO_INCREMENT = 1');

mkv_log('Preparing news posts table...');
$np = $db->prepare('INSERT INTO `msz_news_posts` (`category_id`, `user_id`, `post_is_featured`, `post_title`, `post_text`) VALUES (:category, :user, :featured, :title, :text)');

for($i = 0; $i < 200; ++$i) {
    mkv_log('Creating bogus news post ' . $i . '...');
    $np->bind('category', $ncIds[array_rand($ncIds)]);
    $np->bind('user', mt_rand(1, 2000));
    $np->bind('featured', mt_rand(0, 1));
    $np->bind('title', mb_substr($newsPostsTitles->generate(), 0, 200, 'utf-8'));
    $np->bind('text', mb_substr($newsPostsTexts->generate(), 0, 60000, 'utf-8'));
    $np->execute();
}

mkv_log('Opening forum category markov dictionaries...');
$forumCatsNames = new MarkovDictionary(MKV_DICTS . '/forums_cats_names.fmk');
$forumCatsDescs = new MarkovDictionary(MKV_DICTS . '/forums_cats_descs.fmk');

mkv_log('Nuking forum category table...');
$db->exec('DELETE FROM `msz_forum_categories`');
$db->exec('ALTER TABLE `msz_forum_categories` AUTO_INCREMENT = 1');

mkv_log('Inserting 5 root categories and permissions...');
for($i = 0; $i < 5; ++$i) {
    mkv_log('Inserting bogus category ' . $i . '...');
    $ic = $db->prepare('INSERT INTO `msz_forum_categories` (`forum_name`, `forum_type`) VALUES (:name, 1)');
    $ic->bind('name', mb_substr($forumCatsNames->generate(), 0, 240, 'utf-8'));
    $ic->execute();

    mkv_log('Inserting permissions for bogus category ' . $i . '...');
    $ip = $db->prepare('INSERT INTO `msz_forum_permissions` (`forum_id`, `forum_perms_allow`) VALUES (:cat, 3)');
    $ip->bind('cat', $i + 1);
    $ip->execute();
}

$categories = mt_rand(20, 40);
mkv_log('Inserting ' . $categories . ' forum sections...');

$catIds = [];
for($i = 0; $i < $categories; ++$i) {
    mkv_log('Inserting bogus forum section ' . $i . '...');
    $ic = $db->prepare('INSERT INTO `msz_forum_categories` (`forum_name`, `forum_type`, `forum_description`, `forum_parent`) VALUES (:name, 0, :desc, :parent)');
    $ic->bind('name', mb_substr($forumCatsNames->generate(), 0, 240, 'utf-8'));
    $ic->bind('desc', mb_substr($forumCatsDescs->generate(), 0, 1200, 'utf-8'));
    $ic->bind('parent', mt_rand(1, 5));
    $ic->execute();
    $catIds[] = $db->lastId();
}

mkv_log('Opening forum topic title markov dictionary...');
$forumTopicsTitles = new MarkovDictionary(MKV_DICTS . '/forums_topics_titles.fmk');

mkv_log('Nuking forum topics table...');
$db->exec('DELETE FROM `msz_forum_topics`');
$db->exec('ALTER TABLE `msz_forum_topics` AUTO_INCREMENT = 1');

mkv_log('Preparing forum topic insertion statement...');
$ft = $db->prepare('INSERT INTO `msz_forum_topics` (`forum_id`, `user_id`, `topic_type`, `topic_title`, `topic_count_views`, `topic_created`, `topic_bumped`, `topic_deleted`, `topic_locked`) VALUES (:cat, :user, :type, :title, :views, FROM_UNIXTIME(:created), FROM_UNIXTIME(:bumped), FROM_UNIXTIME(:deleted), FROM_UNIXTIME(:locked))');

$topics = mt_rand(200, 2000);
mkv_log('Creating ' . $topics . ' bogus forum topics...');

$topIds = [];
for($i = 0; $i < $topics; ++$i) {
    mkv_log('Creating bogus topic ' . $i . '...');
    $userId = mt_rand(-100, 2000);
    if($userId < 1)
        $userId = null;
    $type = mt_rand(-1000, 2);
    if($type < 1)
        $type = 0;
    $ft->bind('cat', $catIds[array_rand($catIds)]);
    $ft->bind('user', $userId);
    $ft->bind('type', $type);
    $ft->bind('title', mb_substr($forumTopicsTitles->generate(), 0, 240, 'utf-8'));
    $ft->bind('views', mt_rand(0, 10000));
    $ft->bind('created', mt_rand(1, 0x7FFFFFFF));
    $ft->bind('bumped', mt_rand(1, 0x7FFFFFFF));
    $ft->bind('deleted', mt_rand(0, 10000) > 9999 ? mt_rand(1, 0x7FFFFFFF) : null);
    $ft->bind('locked', mt_rand(0, 10000) > 9900 ? mt_rand(1, 0x7FFFFFFF) : null);
    $ft->execute();
    $topIds[] = $db->lastId();
}

mkv_log('Opening forum post text markov dictionary...');
$forumPostsTexts = new MarkovDictionary(MKV_DICTS . '/forums_posts_texts.fmk');

mkv_log('Nuking forum posts table...');
$db->exec('DELETE FROM `msz_forum_posts`');
$db->exec('ALTER TABLE `msz_forum_posts` AUTO_INCREMENT = 1');

mkv_log('Preparing forum post insertion statement...');
$fp = $db->prepare('INSERT INTO `msz_forum_posts` (`topic_id`, `forum_id`, `user_id`, `post_ip`, `post_text`, `post_parse`, `post_display_signature`, `post_created`, `post_edited`, `post_deleted`) VALUES (:topic, 1, :user, :addr, :text, :parse, :sig, FROM_UNIXTIME(:created), FROM_UNIXTIME(:edited), FROM_UNIXTIME(:deleted))');

$topCount = count($topIds);
for($t = 0; $t < $topCount; ++$t) {
    $posts = mt_rand(1, 600);
    $topId = $topIds[$t];

    mkv_log('Inserting ' . $posts . ' bogus forum posts for bogus topic ' . $topId . '...');

    $fp->bind('topic', $topId);

    for($i = 0; $i < $posts; ++$i) {
        mkv_log('Inserting bogus post ' . $i . ' into bogus topic ' . $topId . '...');

        $userId = mt_rand(-100, 2000);
        if($userId < 1)
            $userId = null;
        $fp->bind('user', $userId);
        $fp->bind('addr', random_bytes(mt_rand(0, 1) ? 4 : 16));
        $fp->bind('text', mb_substr($forumPostsTexts->generate(), 0, 60000, 'utf-8'));
        $fp->bind('parse', mt_rand(0, 2));
        $fp->bind('sig', mt_rand(0, 1000) > 900 ? 0 : 1);
        $fp->bind('created', mt_rand(1, 0x7FFFFFFF));
        $fp->bind('created', mt_rand(1, 0x7FFFFFFF));
        $fp->bind('edited', mt_rand(0, 1000) > 900 ? mt_rand(1, 0x7FFFFFFF) : null);
        $fp->bind('deleted', mt_rand(0, 10000) > 9000 ? mt_rand(1, 0x7FFFFFFF) : null);
        $fp->execute();
    }
}

mkv_log('Running slow cron once more...');

// running cron after fuckery
(new \Misuzu\Console\Commands\CronCommand)->dispatch(
    new \Misuzu\Console\CommandArgs(['--slow'])
);

mkv_log('Done! Enjoy your garbage filled forum.');
