<?php
/**
 * SaveToWishlist class.
 *
 * @package SaveToWishlist\Classes
 * @since 1.0.0
 */
namespace SaveToWishlist\Classes;

use SaveToWishlist\Abstracts\Singleton;
use SaveToWishlist\Classes\API\API_Admin_Settings;
use SaveToWishlist\Classes\API\API_Frontend_Endpoints;
use SaveToWishlist\Classes\API\API_Admin_Wishlists;
use SaveToWishlist\Classes\API\API_Admin_Importer;
use SaveToWishlist\Classes\Admin\Admin_Hooks;
use SaveToWishlist\Classes\Frontend\Frontend_Hooks;
use SaveToWishlist\Helpers\Helper_Database;

// Integrations Classes.
use SaveToWishlist\Classes\Integrations\WooCommerce;
use SaveToWishlist\Classes\Integrations\Cache_Exclusions;
use SaveToWishlist\Classes\Integrations\WPML_Support;
use SaveToWishlist\Classes\Integrations\Product_Search;

/**
 * Class SaveToWishlist
 *
 * This class serves as the main plugin class.
 */
class SaveToWishlist extends Singleton {
    /**
     * The plugin classes.
     *
     * @var array
     */
    private $objects = array();

    /**
     * Constructor.
     */
    public function __construct() {
        // Load the plugin classes that should be run on boot.
        $this->objects = array(
            // API Classes.
            API_Admin_Settings::instance(),
            API_Admin_Wishlists::instance(),
            API_Admin_Importer::instance(),

            // Admin Classes.
            Admin_Hooks::instance(),

            // Frontend Classes.
            Frontend_Hooks::instance(),
            API_Frontend_Endpoints::instance(),

            // Integrations Classes.
            WooCommerce::instance(),
            WPML_Support::instance(),
            Product_Search::instance(),

            // Cache Exclusions.
            Cache_Exclusions::instance(),
        );
    }

    /**
     * Init the plugin.
     */
    public function boot() {
        // Self-heal the schema before any module can query the wishlist tables.
        // Covers file-level plugin updates that skip the activation hook,
        // dropped tables, partial restores, and future schema additions.
        Helper_Database::maybe_install_schema();

        /**
         * Run the plugin classes.
         *
         * Make sure that the classes to be run extends the abstract class or has
         * implemented a `run` method.
         */
        foreach ( $this->objects as $object ) {
            if ( ! method_exists( $object, 'run' ) ) {
                _doing_it_wrong(
                    __METHOD__,
                    'The class does not have a run method. Please make sure to extend the Singleton class.',
                    esc_html( STWLITE_VERSION )
                );
                continue;
            }

            $class_object = strtolower( wp_basename( get_class( $object ) ) );

            $this->objects[ $class_object ] = apply_filters(
                'stwlite_run_object',
                $object,
                $class_object,
                $this
            );

            $this->objects[ $class_object ]->run();
        }
    }
}
