<?php
/*
 * ----------------------------------------------------------------------
 *
 *                          Borlabs Cookie
 *                      developed by Borlabs
 *
 * ----------------------------------------------------------------------
 *
 * Copyright 2018 Borlabs - Benjamin A. Bornschein. All rights reserved.
 * This file may not be redistributed in whole or significant part.
 * Content of this file is protected by international copyright laws.
 *
 * ----------------- Borlabs Cookie IS NOT FREE SOFTWARE -----------------
 *
 * @copyright Borlabs - Benjamin A. Bornschein, https://borlabs.io
 * @author Benjamin A. Bornschein, Borlabs ben@borlabs.io
 *
 */

namespace BorlabsCookie\Cookie;

class Install
{

    private static $instance;

    public static function getInstance()
    {
        if (null === self::$instance) {
            self::$instance = new self;
        }

        return self::$instance;
    }

    private function __clone()
    {
    }

    private function __wakeup()
    {
    }

    public function __construct()
    {
    }

    /**
     * installPlugin function.
     *
     * @access public
     * @return void
     */
    public function installPlugin()
    {
        global $wpdb;

        $tableNameCookieLog = $wpdb->base_prefix.'borlabs_cookie_log';
        $tableNameBlockedContentTypes = $wpdb->base_prefix.'borlabs_cookie_blocked_content_types';
        $charsetCollate = $wpdb->get_charset_collate();

        $sqlCreateTableCookieLog = $this->getCreateTableStatementCookieLog($tableNameCookieLog, $charsetCollate);
        $sqlCreateTableBlockedContentTypes = $this->getCreateTableStatementBlockedContentTypes($tableNameBlockedContentTypes, $charsetCollate);

        require_once ABSPATH.'wp-admin/includes/upgrade.php';

        dbDelta($sqlCreateTableCookieLog);
        dbDelta($sqlCreateTableBlockedContentTypes);

        // Check if key exists
        $checkKeyA = $wpdb->query("SHOW INDEXES FROM `".$tableNameCookieLog."` WHERE `Key_name`='index_a'");

        if (!$checkKeyA) {
            // Set key
            $sqlAddKey = "ALTER TABLE `".$tableNameCookieLog."` ADD KEY `index_a` (`stamp`,`option`,`uid`)";
            $wpdb->query($sqlAddKey);
        }

        $checkKeyB = $wpdb->query("SHOW INDEXES FROM `".$tableNameCookieLog."` WHERE `Key_name`='index_b'");

        if (!$checkKeyB) {
            // Set key
            $sqlAddKey = "ALTER TABLE `".$tableNameCookieLog."` ADD KEY `index_b` (`uid`,`stamp`,`option`)";
            $wpdb->query($sqlAddKey);
        }

        // Load language package
        load_plugin_textdomain('borlabs-cookie', false, dirname(BORLABS_COOKIE_SLUG).'/languages/');

        // Add default Blocked Content Types
        \BorlabsCookie\Cookie\Backend\BlockedContentTypes::getInstance()->checkAndRestoreDefaults();

        update_option('BorlabsCookieVersion', BORLABS_COOKIE_VERSION, 'no');

        // Add cache folder
        if (!file_exists(WP_CONTENT_DIR.'/cache')) {
            if (is_writable(WP_CONTENT_DIR)) {
                mkdir(WP_CONTENT_DIR.'/cache');
            }
        }

        if (!file_exists(WP_CONTENT_DIR.'/cache/borlabs_cookie')) {
            if (is_writable(WP_CONTENT_DIR.'/cache')) {
                mkdir(WP_CONTENT_DIR.'/cache/borlabs_cookie');
            }
        }

        if (is_multisite()) {
            $allBlogs = $wpdb->get_results('
                SELECT
                    `blog_id`
                FROM
                    `'.$wpdb->base_prefix.'blogs`
            ');

            if (!empty($allBlogs)) {
                $originalBlogId = get_current_blog_id();

                foreach ($allBlogs as $blogData) {
                    if ($blogData->blog_id != 1) {
                        switch_to_blog($blogData->blog_id);

                        $tableNameCookieLog = $wpdb->prefix.'borlabs_cookie_log'; // ->prefix contains base_prefix + blog id
                        $tableNameBlockedContentTypes = $wpdb->prefix.'borlabs_cookie_blocked_content_types'; // ->prefix contains base_prefix + blog id

                        $sqlCreateTableCookieLog = $this->getCreateTableStatementCookieLog($tableNameCookieLog, $charsetCollate);
                        $sqlCreateTableBlockedContentTypes = $this->getCreateTableStatementBlockedContentTypes($tableNameBlockedContentTypes, $charsetCollate);

                        dbDelta($sqlCreateTableCookieLog);
                        dbDelta($sqlCreateTableBlockedContentTypes);

                        // Check if key exists
                        $checkKeyA = $wpdb->query("SHOW INDEXES FROM `".$tableNameCookieLog."` WHERE `Key_name`='index_a'");

                        if (!$checkKeyA) {
                            // Set key
                            $sqlAddKey = "ALTER TABLE `".$tableNameCookieLog."` ADD KEY `index_a` (`stamp`,`option`,`uid`)";
                            $wpdb->query($sqlAddKey);
                        }

                        $checkKeyB = $wpdb->query("SHOW INDEXES FROM `".$tableNameCookieLog."` WHERE `Key_name`='index_b'");

                        if (!$checkKeyB) {
                            // Set key
                            $sqlAddKey = "ALTER TABLE `".$tableNameCookieLog."` ADD KEY `index_b` (`uid`,`stamp`,`option`)";
                            $wpdb->query($sqlAddKey);
                        }

                        // Get language of the blog
                        $blogLanguage = substr(get_option('WPLANG', 'en_US'), 0, 2);

                        if ($blogLanguage === 'de') {
                            // Load german language pack
                            load_textdomain('borlabs-cookie', BORLABS_COOKIE_PLUGIN_PATH.'languages/borlabs-cookie-de_DE.mo');
                        } else {
                            // Load unload language pack
                            unload_textdomain('borlabs-cookie');
                        }

                        // Add default Blocked Content Types
                        \BorlabsCookie\Cookie\Backend\BlockedContentTypes::getInstance()->checkAndRestoreDefaults($blogLanguage);

                        update_option('BorlabsCookieVersion', BORLABS_COOKIE_VERSION, 'no');
                    }
                }

                switch_to_blog($originalBlogId);
            }
        }
    }

    public function getCreateTableStatementCookieLog($tableName, $charsetCollate)
    {
        return "CREATE TABLE IF NOT EXISTS ".$tableName." (
            `log_id` int(11) unsigned NOT NULL AUTO_INCREMENT,
            `uid` varchar(35) NOT NULL DEFAULT '',
            `option` varchar(35) DEFAULT NULL,
            `stamp` datetime DEFAULT NULL,
            PRIMARY KEY (`log_id`),
            KEY `index_a` (`stamp`,`option`,`uid`),
            KEY `index_b` (`uid`,`stamp`,`option`)
        ) ".$charsetCollate.";";
    }


    public function getCreateTableStatementBlockedContentTypes($tableName, $charsetCollate)
    {
        /*
            id: e.g. 1
            type_id: e.g. youtube
            language: e.g. en
            name: e.g. YouTube
            description: e.g. description or information about this BCT
            hosts: eg. youtube.com, youtu.be - optional value
            preview_html: HTML code that functions as a preview of the blocked content
            global_js: JavaScript code executed once when this type of content is unblocked
            init_js: JavaScript code executed every time when this type of content is unblocked
            settings: settings for this blocked content
            status: only active BCT will be loaded in the frontend
            undeletable: if the BCT can not be deleted
        */
        return "CREATE TABLE IF NOT EXISTS ".$tableName." (
            `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
            `type_id` varchar(35) NOT NULL DEFAULT '',
            `language` varchar(14) NOT NULL DEFAULT '',
            `name` varchar(100) NOT NULL DEFAULT '',
            `description` text NOT NULL DEFAULT '',
            `hosts` TEXT NOT NULL DEFAULT '',
            `preview_html` TEXT NOT NULL DEFAULT '',
            `global_js` TEXT NOT NULL DEFAULT '',
            `init_js` TEXT NOT NULL DEFAULT '',
            `settings` TEXT NOT NULL DEFAULT '',
            `status` int(1) unsigned NOT NULL DEFAULT '0',
            `undeletable` int(1) unsigned NOT NULL DEFAULT '0',
            PRIMARY KEY (`id`),
            UNIQUE KEY (`type_id`, `language`)
        ) ".$charsetCollate.";";
    }

    public function checkIfTableExists($tableName)
    {
        global $wpdb;

        $tableResult = $wpdb->get_results('
            SELECT
                `TABLE_NAME`
            FROM
                `information_schema`.`TABLES`
            WHERE
                `TABLE_SCHEMA`="'.esc_sql($wpdb->dbname).'"
                AND
                `TABLE_NAME`="'.esc_sql($tableName).'"
        ');

        if (!empty($tableResult[0]->TABLE_NAME)) {
            return true;
        } else {
            return false;
        }
    }

    public function checkTypeOfColumn($tableName, $columnName, $expectedType)
    {
        global $wpdb;

        $tableResult = $wpdb->get_results('
            SELECT
                `DATA_TYPE`
            FROM
                `information_schema`.`COLUMNS`
            WHERE
                `TABLE_SCHEMA`="'.esc_sql($wpdb->dbname).'"
                AND
                `TABLE_NAME`="'.esc_sql($tableName).'"
                AND
                `COLUMN_NAME`="'.esc_sql($columnName).'"
        ');

        if (!empty($tableResult[0]->DATA_TYPE) && strtolower($tableResult[0]->DATA_TYPE) == strtolower($expectedType)) {
            return true;
        } else {
            return false;
        }
    }
}
