<?php

abstract class ActionScheduler_Abstract_Schema
{
    protected $schema_version = 1;
    protected $db_version;
    protected $tables = array();
    public function init()
    {
    }
    public function register_tables($force_update = false)
    {
        global $wpdb;
        foreach ($this->tables as $table) {
            $wpdb->tables[] = $table;
            $name = $this->get_full_table_name($table);
            $wpdb->{$table} = $name;
        }
        if ($this->schema_update_required() || $force_update) {
            foreach ($this->tables as $table) {
                do_action('action_scheduler_before_schema_update', $table, $this->db_version);
                $this->update_table($table);
            }
            $this->mark_schema_update_complete();
        }
    }
    protected abstract function get_table_definition($table);
    private function schema_update_required()
    {
        $option_name = 'schema-' . static::class;
        $this->db_version = get_option($option_name, 0);
        if (0 === $this->db_version) {
            $plugin_option_name = 'schema-';
            switch (static::class) {
                case 'ActionScheduler_StoreSchema':
                    $plugin_option_name .= 'Action_Scheduler\\Custom_Tables\\DB_Store_Table_Maker';
                    break;
                case 'ActionScheduler_LoggerSchema':
                    $plugin_option_name .= 'Action_Scheduler\\Custom_Tables\\DB_Logger_Table_Maker';
                    break;
            }
            $this->db_version = get_option($plugin_option_name, 0);
            delete_option($plugin_option_name);
        }
        return version_compare($this->db_version, $this->schema_version, '<');
    }
    private function mark_schema_update_complete()
    {
        $option_name = 'schema-' . static::class;
        $value_to_save = (string) $this->schema_version . '.0.' . time();
        update_option($option_name, $value_to_save);
    }
    private function update_table($table)
    {
        require_once ABSPATH . 'wp-admin/includes/upgrade.php';
        $definition = $this->get_table_definition($table);
        if ($definition) {
            $updated = dbDelta($definition);
            foreach ($updated as $updated_table => $update_description) {
                if (strpos($update_description, 'Created table') === 0) {
                    do_action('action_scheduler/created_table', $updated_table, $table);
                }
            }
        }
    }
    protected function get_full_table_name($table)
    {
        return $GLOBALS['wpdb']->prefix . $table;
    }
    public function tables_exist()
    {
        global $wpdb;
        $existing_tables = $wpdb->get_col('SHOW TABLES');
        $expected_tables = array_map(function ($table_name) use($wpdb) {
            return $wpdb->prefix . $table_name;
        }, $this->tables);
        return count(array_intersect($existing_tables, $expected_tables)) === count($expected_tables);
    }
}