<?php

namespace WPUM\Carbon_Fields\Provider;

use WPUM\Carbon_Fields\Pimple\Container as PimpleContainer;
use WPUM\Carbon_Fields\Pimple\ServiceProviderInterface;
use WPUM\Carbon_Fields\Container\Condition\Factory as ConditionFactory;
use WPUM\Carbon_Fields\Container\Fulfillable\Fulfillable_Collection;
class Container_Condition_Provider implements ServiceProviderInterface
{
    /**
     * Install dependencies in IoC container
     *
     * @param  PimpleContainer $ioc
     */
    public function register(PimpleContainer $ioc)
    {
        $this->install_conditions($ioc);
        $this->install_comparers($ioc);
        $this->install_translators($ioc);
        $this->install_container_conditions($ioc);
    }
    /**
     * Install all codition types and the condition factory
     *
     * @param  PimpleContainer $ioc
     */
    protected function install_conditions($ioc)
    {
        $ioc['container_condition_factory'] = function ($ioc) {
            return new ConditionFactory($ioc['container_conditions']);
        };
        $ioc['container_condition_fulfillable_collection'] = $ioc->factory(function ($ioc) {
            return new Fulfillable_Collection($ioc['container_condition_factory'], $ioc['container_condition_translator_array']);
        });
        $ioc['container_conditions'] = function () {
            return new PimpleContainer();
        };
        $cc_ioc = $ioc['container_conditions'];
        $cc_ioc['boolean'] = $cc_ioc->factory(function () use($ioc) {
            $condition = new \WPUM\Carbon_Fields\Container\Condition\Boolean_Condition();
            $condition->set_comparers(array($ioc['container_condition_comparers']['equality']));
            return $condition;
        });
        $cc_ioc['post_id'] = $cc_ioc->factory(function () use($ioc) {
            $condition = new \WPUM\Carbon_Fields\Container\Condition\Post_ID_Condition();
            $condition->set_comparers($ioc['container_condition_comparer_collections']['generic']);
            return $condition;
        });
        $cc_ioc['post_parent_id'] = $cc_ioc->factory(function () use($ioc) {
            $condition = new \WPUM\Carbon_Fields\Container\Condition\Post_Parent_ID_Condition();
            $condition->set_comparers($ioc['container_condition_comparer_collections']['generic']);
            return $condition;
        });
        $cc_ioc['post_ancestor_id'] = $cc_ioc->factory(function () use($ioc) {
            $condition = new \WPUM\Carbon_Fields\Container\Condition\Post_Ancestor_ID_Condition();
            $condition->set_comparers($ioc['container_condition_comparer_collections']['array']);
            return $condition;
        });
        $cc_ioc['post_type'] = $cc_ioc->factory(function () use($ioc) {
            $condition = new \WPUM\Carbon_Fields\Container\Condition\Post_Type_Condition();
            $condition->set_comparers($ioc['container_condition_comparer_collections']['nonscalar']);
            return $condition;
        });
        $cc_ioc['post_format'] = $cc_ioc->factory(function () use($ioc) {
            $condition = new \WPUM\Carbon_Fields\Container\Condition\Post_Format_Condition();
            $condition->set_comparers($ioc['container_condition_comparer_collections']['nonscalar']);
            return $condition;
        });
        $cc_ioc['post_level'] = $cc_ioc->factory(function () use($ioc) {
            $condition = new \WPUM\Carbon_Fields\Container\Condition\Post_Level_Condition();
            $condition->set_comparers($ioc['container_condition_comparer_collections']['generic']);
            return $condition;
        });
        $cc_ioc['post_template'] = $cc_ioc->factory(function () use($ioc) {
            $condition = new \WPUM\Carbon_Fields\Container\Condition\Post_Template_Condition();
            $condition->set_comparers($ioc['container_condition_comparer_collections']['nonscalar']);
            return $condition;
        });
        $cc_ioc['post_term'] = $cc_ioc->factory(function () use($ioc) {
            $condition = new \WPUM\Carbon_Fields\Container\Condition\Post_Term_Condition($ioc['wp_toolset']);
            $condition->set_comparers(array(
                // Only support the custom comparer as this condition has its own comparison methods
                $ioc['container_condition_comparers']['custom'],
            ));
            return $condition;
        });
        $cc_ioc['term'] = $cc_ioc->factory(function () use($ioc) {
            $condition = new \WPUM\Carbon_Fields\Container\Condition\Term_Condition($ioc['wp_toolset']);
            $condition->set_comparers(array(
                // Only support the custom comparer as this condition has its own comparison methods
                $ioc['container_condition_comparers']['custom'],
            ));
            return $condition;
        });
        $cc_ioc['term_taxonomy'] = $cc_ioc->factory(function () use($ioc) {
            $condition = new \WPUM\Carbon_Fields\Container\Condition\Term_Taxonomy_Condition();
            $condition->set_comparers($ioc['container_condition_comparer_collections']['nonscalar']);
            return $condition;
        });
        $cc_ioc['term_level'] = $cc_ioc->factory(function () use($ioc) {
            $condition = new \WPUM\Carbon_Fields\Container\Condition\Term_Level_Condition();
            $condition->set_comparers($ioc['container_condition_comparer_collections']['generic']);
            return $condition;
        });
        $cc_ioc['term_parent'] = $cc_ioc->factory(function () use($ioc) {
            $condition = new \WPUM\Carbon_Fields\Container\Condition\Term_Parent_Condition($ioc['wp_toolset']);
            $condition->set_comparers($ioc['container_condition_comparer_collections']['generic']);
            return $condition;
        });
        $cc_ioc['term_ancestor'] = $cc_ioc->factory(function () use($ioc) {
            $condition = new \WPUM\Carbon_Fields\Container\Condition\Term_Ancestor_Condition($ioc['wp_toolset']);
            $condition->set_comparers($ioc['container_condition_comparer_collections']['array']);
            return $condition;
        });
        $cc_ioc['user_id'] = $cc_ioc->factory(function () use($ioc) {
            $condition = new \WPUM\Carbon_Fields\Container\Condition\User_ID_Condition();
            $condition->set_comparers($ioc['container_condition_comparer_collections']['generic']);
            return $condition;
        });
        $cc_ioc['user_role'] = $cc_ioc->factory(function () use($ioc) {
            $condition = new \WPUM\Carbon_Fields\Container\Condition\User_Role_Condition();
            $condition->set_comparers($ioc['container_condition_comparer_collections']['array']);
            return $condition;
        });
        $cc_ioc['user_capabiltiy'] = $cc_ioc->factory(function () use($ioc) {
            $condition = new \WPUM\Carbon_Fields\Container\Condition\User_Capability_Condition();
            $condition->set_comparers(array(
                // Only support the custom comparer as this condition has its own comparison methods
                $ioc['container_condition_comparers']['custom'],
            ));
            return $condition;
        });
        $cc_ioc['blog_id'] = $cc_ioc->factory(function () use($ioc) {
            $condition = new \WPUM\Carbon_Fields\Container\Condition\Blog_ID_Condition();
            $condition->set_comparers($ioc['container_condition_comparer_collections']['generic']);
            return $condition;
        });
        $cc_ioc['current_user_id'] = $cc_ioc->factory(function () use($ioc) {
            $condition = new \WPUM\Carbon_Fields\Container\Condition\Current_User_ID_Condition();
            $condition->set_comparers($ioc['container_condition_comparer_collections']['generic']);
            return $condition;
        });
        $cc_ioc['current_user_role'] = $cc_ioc->factory(function () use($ioc) {
            $condition = new \WPUM\Carbon_Fields\Container\Condition\Current_User_Role_Condition();
            $condition->set_comparers($ioc['container_condition_comparer_collections']['array']);
            return $condition;
        });
        $cc_ioc['current_user_capability'] = $cc_ioc->factory(function () use($ioc) {
            $condition = new \WPUM\Carbon_Fields\Container\Condition\Current_User_Capability_Condition();
            $condition->set_comparers(array(
                // Only support the custom comparer as this condition has its own comparison methods
                $ioc['container_condition_comparers']['custom'],
            ));
            return $condition;
        });
    }
    /**
     * Install all condition comparers
     *
     * @param  PimpleContainer $ioc
     */
    protected function install_comparers($ioc)
    {
        $ioc['container_condition_comparers'] = function () {
            return new PimpleContainer();
        };
        $ioc['container_condition_comparers']['equality'] = function () {
            return new \WPUM\Carbon_Fields\Container\Condition\Comparer\Equality_Comparer();
        };
        $ioc['container_condition_comparers']['any_equality'] = function () {
            return new \WPUM\Carbon_Fields\Container\Condition\Comparer\Any_Equality_Comparer();
        };
        $ioc['container_condition_comparers']['contain'] = function () {
            return new \WPUM\Carbon_Fields\Container\Condition\Comparer\Contain_Comparer();
        };
        $ioc['container_condition_comparers']['any_contain'] = function () {
            return new \WPUM\Carbon_Fields\Container\Condition\Comparer\Any_Contain_Comparer();
        };
        $ioc['container_condition_comparers']['scalar'] = function () {
            return new \WPUM\Carbon_Fields\Container\Condition\Comparer\Scalar_Comparer();
        };
        $ioc['container_condition_comparers']['custom'] = function () {
            return new \WPUM\Carbon_Fields\Container\Condition\Comparer\Custom_Comparer();
        };
        $ioc['container_condition_comparer_collections'] = function () {
            return new PimpleContainer();
        };
        $ioc['container_condition_comparer_collections']['generic'] = function () use($ioc) {
            return array($ioc['container_condition_comparers']['equality'], $ioc['container_condition_comparers']['contain'], $ioc['container_condition_comparers']['scalar'], $ioc['container_condition_comparers']['custom']);
        };
        $ioc['container_condition_comparer_collections']['nonscalar'] = function () use($ioc) {
            return array($ioc['container_condition_comparers']['equality'], $ioc['container_condition_comparers']['contain'], $ioc['container_condition_comparers']['custom']);
        };
        $ioc['container_condition_comparer_collections']['array'] = function () use($ioc) {
            return array($ioc['container_condition_comparers']['any_equality'], $ioc['container_condition_comparers']['any_contain'], $ioc['container_condition_comparers']['custom']);
        };
    }
    /**
     * Install all codition translators
     *
     * @param  PimpleContainer $ioc
     */
    protected static function install_translators($ioc)
    {
        $ioc['container_condition_translator_array'] = function ($ioc) {
            return new \WPUM\Carbon_Fields\Container\Fulfillable\Translator\Array_Translator($ioc['container_condition_factory']);
        };
        $ioc['container_condition_translator_json'] = function ($ioc) {
            return new \WPUM\Carbon_Fields\Container\Fulfillable\Translator\Json_Translator($ioc['container_condition_factory']);
        };
    }
    /**
     * Install all container coditions
     *
     * @param  PimpleContainer $ioc
     */
    protected function install_container_conditions($ioc)
    {
        // add current_user_* static condition types to all containers
        add_filter('carbon_fields_container_static_condition_types', function ($condition_types, $container_type, $container) {
            return \array_merge($condition_types, array('current_user_id', 'current_user_role', 'current_user_capability'));
        }, 10, 3);
        // add container-specific conditions
        add_filter('carbon_fields_post_meta_container_static_condition_types', array($this, 'filter_post_meta_container_static_condition_types'), 10, 3);
        add_filter('carbon_fields_post_meta_container_dynamic_condition_types', array($this, 'filter_post_meta_container_dynamic_condition_types'), 10, 3);
        add_filter('carbon_fields_term_meta_container_static_condition_types', array($this, 'filter_term_meta_container_static_condition_types'), 10, 3);
        add_filter('carbon_fields_term_meta_container_dynamic_condition_types', array($this, 'filter_term_meta_container_dynamic_condition_types'), 10, 3);
        add_filter('carbon_fields_user_meta_container_static_condition_types', array($this, 'filter_user_meta_container_static_condition_types'), 10, 3);
        add_filter('carbon_fields_user_meta_container_dynamic_condition_types', array($this, 'filter_user_meta_container_dynamic_condition_types'), 10, 3);
        add_filter('carbon_fields_theme_options_container_static_condition_types', array($this, 'filter_theme_options_container_static_condition_types'), 10, 3);
    }
    /**
     * Filter the Post_Meta_Container static condition types
     *
     * @param  array<string>                     $condition_types
     * @param  Carbon_Fields\Container\Container $container
     * @return array<string>
     */
    public function filter_post_meta_container_static_condition_types($condition_types, $container_type, $container)
    {
        return \array_merge($condition_types, array('post_id', 'post_type'));
    }
    /**
     * Filter the Post_Meta_Container dynamic condition types
     *
     * @param  array<string>                     $condition_types
     * @param  Carbon_Fields\Container\Container $container
     * @return array<string>
     */
    public function filter_post_meta_container_dynamic_condition_types($condition_types, $container_type, $container)
    {
        return \array_merge($condition_types, array('post_parent_id', 'post_ancestor_id', 'post_format', 'post_level', 'post_template', 'post_term'));
    }
    /**
     * Filter the Term_Meta_Container static condition types
     *
     * @param  array<string>                     $condition_types
     * @param  Carbon_Fields\Container\Container $container
     * @return array<string>
     */
    public function filter_term_meta_container_static_condition_types($condition_types, $container_type, $container)
    {
        return \array_merge($condition_types, array('term', 'term_taxonomy'));
    }
    /**
     * Filter the Term_Meta_Container dynamic condition types
     *
     * @param  array<string>                     $condition_types
     * @param  Carbon_Fields\Container\Container $container
     * @return array<string>
     */
    public function filter_term_meta_container_dynamic_condition_types($condition_types, $container_type, $container)
    {
        return \array_merge($condition_types, array('term_level', 'term_parent', 'term_ancestor'));
    }
    /**
     * Filter the User_Meta_Container static condition types
     *
     * @param  array<string>                     $condition_types
     * @param  Carbon_Fields\Container\Container $container
     * @return array<string>
     */
    public function filter_user_meta_container_static_condition_types($condition_types, $container_type, $container)
    {
        return \array_merge($condition_types, array('user_id', 'user_capability'));
    }
    /**
     * Filter the User_Meta_Container dynamic condition types
     *
     * @param  array<string>                     $condition_types
     * @param  Carbon_Fields\Container\Container $container
     * @return array<string>
     */
    public function filter_user_meta_container_dynamic_condition_types($condition_types, $container_type, $container)
    {
        return \array_merge($condition_types, array('user_role'));
    }
    /**
     * Filter the Theme_Options_Container static condition types
     *
     * @param  array<string>                     $condition_types
     * @param  Carbon_Fields\Container\Container $container
     * @return array<string>
     */
    public function filter_theme_options_container_static_condition_types($condition_types, $container_type, $container)
    {
        return \array_merge($condition_types, array('blog_id'));
    }
}
