<?php

namespace Fab\Plugin;

// Exit if accessed directly.
if ( ! defined( 'ABSPATH' ) ) {
    exit;
}

/**
 * Helper library for Fab plugins
 *
 * @package    Fab
 * @subpackage Fab\Includes
 */
class Config {

    // Load traits.
    use \Fab\Plugin\Helper\Singleton;

    /**
     * Config instance
     *
     * @access   protected
     * @var      object    $config  Config object
     */
    protected $config;

    /**
     * Get config
     * - Config: is an object that contains the config for the plugin (name, version, production, etc)
     * - Options: is an object that contains the options for the plugin (fab_animation, fab_design, etc), Options are stored in database.
     *
     * @return object
     */
    public function getConfig() {
        // Reconstruct config if not exists.
        if ( ! $this->config ) {
            // Prepare config requirement variables.
            $directory = dirname( __DIR__, 2 );
            $options   = get_option( 'fab_config' );
            $base_file = sprintf( '%s/%s.php', $directory, basename( $directory ) );
            $path      = $this->getPath( $base_file );

            // Initiate config.
            // We use file_get_contents instead of wp_remote_get, due to fatal error on some servers.
            // This is a workaround to ensure that the config is always loaded.
            $config          = file_get_contents( $path['plugin_path'] . 'config.json' );
            $config          = json_decode( $config );
            $config->path    = $path;
            $config->options = ( $options ) ? $options : new \stdClass();

            // Merge config, this will merge default config with options .
            // This process is required to ensure that the config is always up to date .
            $config->options = \Fab\Plugin\Helper::getInstance()->ArrayMergeRecursive(
                (array) $config->default,
                (array) $config->options
            );

            // Update config to database if not exists.
            $config_db = (array) $options;
            if ( empty( $config_db ) || ! $config_db ) {
                update_option( 'fab_config', (object) $config );
            }

            // Set config to class property.
            $this->config = (object) $config;
        }

        // Register config hook to handle legacy options.
        $this->config->options = apply_filters( 'fab_after_setup_options', (object) $this->config->options );

        return $this->config;
    }

    /**
     * WordPress path function
     *
     * @param string $path Path relative to the includes URL.
     * @return array
     */
    public function getPath( $path ) { // phpcs:ignore WordPress.NamingConventions.ValidFunctionName.MethodNameInvalid
        // Get home path.
        if ( ! function_exists( 'get_home_path' ) ) {
            include_once ABSPATH . '/wp-admin/includes/file.php';
        }

        // Get path.
        return array(
            // Free.
            'path'              => $path,
            'home_path'         => get_home_path(),
            'home_url'          => get_home_url(),
            'admin_url'         => admin_url(),
            'plugin_path'       => plugin_dir_path( $path ),
            'plugin_url'        => plugin_dir_url( $path ),
            'view_path'         => plugin_dir_path( $path ) . 'src/View/',
            'upload_dir'        => wp_upload_dir(),
            'ajax_url'          => admin_url( 'admin-ajax.php' ),

            // Premium.
            'premium_view_path' => plugin_dir_path( $path ) . 'premium/View/',
        );
    }

    /**
     * Initiate constants
     *
     * @return void
     */
    public function initiate_constants() {
        // Get config.
        $config = $this->getConfig();

        // Declare Constants.
        define( 'FAB_NAME', $config->name );
        define( 'FAB_VERSION', $config->version );
        define( 'FAB_PRODUCTION', $config->production );
        define( 'FAB_PATH', wp_json_encode( $config->path ) );
        define( 'FAB_PLUGIN_FILE_ENTRY', $config->path['path'] );
        define( 'FAB_PLUGIN_PATH', $config->path['plugin_path'] );
        define( 'FAB_PLUGIN_URL', $config->path['plugin_url'] );
    }

    /**
     * Run functions
     *
     * @return void
     */
    public function run() {
        add_action( 'plugins_loaded', array( $this, 'initiate_constants' ) );
    }
}
