<?php

if (!defined('ABSPATH')) {
    exit;
}

abstract class AIEO_Module_V2_Data {
    
    abstract public static function table_name();
    
    abstract public static function maybe_install();
    
    public static function bootstrap() {}
}

abstract class AIEO_Module_V2_Admin {
    
    abstract public static function bootstrap();
}

abstract class AIEO_Module_V2_Frontend {
    
    abstract public static function contexts();
    
    abstract public static function bootstrap();
}

abstract class AIEO_Module_V2_Compute {
    
    abstract public static function bootstrap();
    
    public static function tick() {}
}

class AIEO_Module_V2_Loader {

    public static function boot_all() {
        $base = AIEO_DIR . 'includes/dmm/modules/_v2/';
        if (!is_dir($base)) { return; }

        $features = scandir($base);
        if (!is_array($features)) { return; }

        
        
        
        
        
        
        $boots = array();
        foreach ($features as $feature) {
            if ($feature === '' || $feature[0] === '.') { continue; }
            $feature_dir = $base . $feature;
            if (!is_dir($feature_dir)) { continue; }
            $boot_file = $feature_dir . '/boot.php';
            if (is_file($boot_file)) {
                $boots[$feature] = $boot_file;
            }
        }
        if (empty($boots)) { return; }

        $context = class_exists('AIEO_Module_Manifest') ? AIEO_Module_Manifest::resolve_context() : 'other_frontend';

        foreach ($boots as $feature => $boot_file) {
            $manifest = include $boot_file;
            if (!is_array($manifest)) { continue; }
            self::boot_one($manifest, $base . $feature, $context);
        }
    }

    private static function boot_one(array $manifest, $feature_dir, $context) {
        
        if (!empty($manifest['data_class']) && !empty($manifest['data_file'])) {
            $f = $feature_dir . '/' . $manifest['data_file'];
            if (is_file($f)) {
                require_once $f;
                if (class_exists($manifest['data_class'])) {
                    call_user_func(array($manifest['data_class'], 'maybe_install'));
                    call_user_func(array($manifest['data_class'], 'bootstrap'));
                }
            }
        }

        $admin_contexts = array('admin', 'admin_ajax');
        if (in_array($context, $admin_contexts, true) && !empty($manifest['admin_class']) && !empty($manifest['admin_file'])) {
            $f = $feature_dir . '/' . $manifest['admin_file'];
            if (is_file($f)) {
                require_once $f;
                if (class_exists($manifest['admin_class'])) {
                    call_user_func(array($manifest['admin_class'], 'bootstrap'));
                }
            }
        }

        if ($context === 'cron' && !empty($manifest['compute_class']) && !empty($manifest['compute_file'])) {
            $f = $feature_dir . '/' . $manifest['compute_file'];
            if (is_file($f)) {
                require_once $f;
                if (class_exists($manifest['compute_class'])) {
                    call_user_func(array($manifest['compute_class'], 'bootstrap'));
                }
            }
        }

        
        
        if (!empty($manifest['frontend_class']) && !empty($manifest['frontend_file']) && !empty($manifest['frontend_contexts'])) {
            $contexts = (array) $manifest['frontend_contexts'];
            $matches = false;
            if (in_array('always_frontend', $contexts, true)) {
                $matches = !in_array($context, $admin_contexts, true) && $context !== 'cron' && $context !== 'rest_api';
            } else {
                $matches = in_array($context, $contexts, true);
            }
            if ($matches) {
                $f = $feature_dir . '/' . $manifest['frontend_file'];
                if (is_file($f)) {
                    require_once $f;
                    if (class_exists($manifest['frontend_class'])) {
                        call_user_func(array($manifest['frontend_class'], 'bootstrap'));
                    }
                }
            }
        }
    }
}
