<?php

abstract class HostGroupEntity
{
    protected InventoryLib $inventoryLib;
    protected string $name = '';
    protected string $description = '';
    protected ?stdClass $filter = null;
    protected string $filter_sql = 'hostkey IS NOT NULL'; // default filter sql that means all hosts should be returned
    protected array $changedItems = [];

    public function __construct()
    {
        $this->inventoryLib = new InventoryLib(new VariablesDictionaryModel());
    }

    /**
     * @return string
     */
    public function getName(): string
    {
        return $this->name;
    }

    /**
     * @param string $name
     */
    public function setName(string $name): void
    {
        $this->changedItems[] = 'name';
        $this->name = $name;
    }

    /**
     * @return string
     */
    public function getDescription(): string
    {
        return $this->description;
    }

    /**
     * @param string $description
     */
    public function setDescription(string|null $description): void
    {
        $this->changedItems[] = 'description';
        $this->description = $description ?? '';
    }

    /**
     * @return object
     */
    public function getFilter(): string
    {
        return $this->filter == null ? '{}' : json_encode($this->filter);
    }

    /**
     * @param stdClass|array|string $filter
     */
    public function setFilter(stdClass|array|string $filter): void
    {
        if (is_array($filter)) {
            // convert to stdClass
            $filter = json_decode(json_encode($filter));
        } elseif (is_string($filter)) {
            $filter = json_decode($filter);
        }
        $this->filter = $filter;
        // there are no other ways to set filter_sql except via changing filter
        // inventory library generates it
        if (!empty($generatedFilterSql = ltrim($this->inventoryLib->applyFilter($filter), 'WHERE'))) {
            $this->filter_sql = $generatedFilterSql;
        }

        $this->changedItems[] = 'filter';
        $this->changedItems[] = 'filter_sql';
    }


    /**
     * @return string
     */
    public function getFilterSql(): string
    {
        return $this->filter_sql;
    }

    public function getChangedItems(): array
    {
        return $this->changedItems;
    }

    public function changedItemsToArray(): array
    {
        $data = [];
        foreach ($this->getChangedItems() as $item) {
            $data[$item] = $this->{"get" . ucfirst(underScoreToCamelCase($item))}();
        }
        return $data;
    }

    abstract public static function sortableColumns(): array;
}
