<?php
namespace NeurogenesisTheme\Core\Api;

class LoadApiRoutes {
    protected $apiNamespace = 'thinko';
    protected $apiVersion = 'v1';
    protected $apiRoutes = [];
    const DELIMITER = ':';
    const PERMISSION_DELIMITER = '@';

    public function __construct($namespace, $version)
    {
        $this->apiNamespace = $namespace;
        $this->apiVersion = $version;
        $this->init();
    }

    public function init()
    {
        $routes = neurogenesis_theme_registry_get('neurogenesis_theme.routes.api', []);

        if (isset($routes[$this->apiNamespace][$this->apiVersion])) {
            $this->apiRoutes = $routes[$this->apiNamespace][$this->apiVersion];
            $this->registerRoutes();
        }
        
    }

    public function registerRoutes()
    {        
        if(!empty($this->apiRoutes)) {
            add_action('rest_api_init', function () {
                foreach ($this->apiRoutes as $routeArgs => $callback) {
                    $route = $this->getRouteArgs($routeArgs);
                    // class methods for permission and api callback
                    $callbacks = $this->buildCallback($callback);

                    register_rest_route($this->apiNamespace . '/' . $this->apiVersion, '/'.$route['path'], [
                        'methods' => $route['methods'],
                        'callback' => $this->apiMethod($callbacks['class'], $callbacks['callback']),
                        'permission_callback' => $this->permissionCallback($callbacks['class'], $callbacks['permission']),
                        'args' => call_user_func([$callbacks['class'], $callbacks['data_arguments']], $callbacks['callback'])
                    ]);
                }
            });
        }
    }

    public function apiMethod($_class, $callback)
    {
        return [new $_class, $callback];
    }

    public function buildCallback($callback)
    {
        $permission = false;
        $_class = $callback[0];
        
        if (strpos($callback[1], self::PERMISSION_DELIMITER) !== false) {
            $str = explode(self::PERMISSION_DELIMITER, $callback[1]);
            $callback = $str[0];
            $permission = $str[1];
        } else {
            $callback = $callback[1];
        }

        return [
            'callback' => $callback,
            'permission' => $permission,
            'class' => $_class,
            'data_arguments' => 'data_arguments',
        ];
    }

    public function permissionCallback($_class, $callback)
    {
        if($callback === false) {
            return [new $_class, 'permission'];  
        }

        return [new $_class, $callback];

    }

    public function getRouteArgs($routeArgs)
    {
        $methods = 'GET';

        if(strpos($routeArgs, self::DELIMITER) !== false) {
            $str = explode(self::DELIMITER, $routeArgs);
            $route = $str[1];            
            $methods = $str[0];
        } else {
            $route = $routeArgs;
        };

        return [
            'methods' => $methods,
            'path'   => $route,
        ];
    }
}