<?php

namespace Module;

use \ReflectionProperty;
use \ReflectionClass;

require_once __DIR__.'/module.class.php';

use \Module\module;

function to_array(object $obj, bool $no_key_for_empty_values = true) {
    $res = array();
    $props_filter = ReflectionProperty::IS_PUBLIC | ReflectionProperty::IS_PROTECTED;
    $properties = (new ReflectionClass($obj))->getProperties($props_filter);
    foreach($properties as $prop) {
        $prop_name = $prop->getName();
        $value = $obj->$prop_name;
        if (empty($value) && $value !== 0 && $no_key_for_empty_values) {
            continue;
        }
        $res[$prop_name] = $value;
        if (is_object($res[$prop_name])) {
            if (method_exists($res[$prop_name], 'to_array')) {
                $res[$prop_name] = $res[$prop_name]->to_array();
            } else {
                $res[$prop_name] = to_array($res[$prop_name]);
            }
        }
    }
    return $res;
}

function normalize_module_class(module $module) {
    $reflect = new ReflectionClass($module);
    $class_with_namespace = $reflect->getName();
    $class_with_namespace_rel = preg_replace('/^'.__NAMESPACE__.'\\\\/', '', $class_with_namespace);
    $class_with_namespace_rel_normalized = preg_replace('/[^a-z0-9-]/', '', str_replace('\\', '-', strtolower($class_with_namespace_rel)));
    return $class_with_namespace_rel_normalized;
}

function module_prefix(object $module) {
    return 'module-'.normalize_module_class($module);
}

class portlet {
    public string $type;
    public string $libelle;
    public string $class;
    public int $order;

    public function __construct(module $module, string $type, string $libelle = '',
                                string $class = '', $order = 20) {
        $this->type = $type;
        $this->libelle = $libelle;
        $this->class = $class;
        // force 'module-<class>' prefix for the class
        if(isset($this->class) && ! empty($this->class)) {
            $prefix = module_prefix($module);
            if (! preg_match("/^$prefix-/", $this->class)) {
                $this->class = "$prefix-".$this->class;
            }
        }
        $this->order = $order;
    }

    public function to_array() {
        return to_array($this);
    }
}

class portlet_action_class {
    const ALLOWED_CLASS = array(
        'direct',
        'direct-with-confirmation',
        'blank',
        'self',
        'overlay'
    );
    protected string $class;
    public function __construct(string $class) {
        $this->class = $class;
        if (! in_array($this->class, self::ALLOWED_CLASS)) {
            throw InvalidArgumentException("invalid class '$class'");
        }
    }
    public function to_array() {
        return 'action-'.$this->class;
    }
}

class portlet_action {
    public string $identifier = '';
    public ?portlet_action_class $action = null;
    public string $method = '';
    public string $crud = '';
    public ?portlet $portlet = null;
    public string $button = '';
    public int $order = 20;
    public string $view = 'view_callback';
    public string $permission_suffix = '';
    public array $condition = array();
    public array $callback = array();

    public function __construct(module $module, string $identifier) {
        $this->identifier = $identifier;
        // force 'module-<class>' prefix for the identifier
        if(isset($this->identifier) && ! empty($this->identifier)) {
            $prefix = module_prefix($module);
            if (! preg_match("/^$prefix-/", $this->identifier)) {
                $this->identifier = "$prefix-".$this->identifier;
            }
        }
    }

    public function to_array() {
        return to_array($this);
    }
}
