<?php
require_once APPPATH . 'models/traits/InventoryLibTrait.php';

abstract class BaseRuleReport
{
    use InventoryLibTrait;
    public const ALL_TYPE = 'all';
    public const PASSING_TYPE = 'passing';
    public const FAILING_TYPE = 'failing';

    protected $conditionMustBeMet;
    protected $type;

    protected $defaultColumns = [
        'Hosts.HostName AS "Host name"',
        'inventory_new.values->>\'OS\' as "OS"',
        'Hosts.IPAddress AS "IP address"',
        'Hosts.LastReportTimeStamp AS "Last report time"',
    ];

    public function __construct($conditionMustBeMet, $type)
    {
        $this->conditionMustBeMet = $conditionMustBeMet;
        $this->type = $type;
        $this->addResultColumn();
        $this->loadInventoryLib();
    }

    abstract public function getReportSql($sql, CF_Rule $rule);

    /**
     * @param $sql
     * @return string
     */
    protected function getFilter($sql, $joinInventory = false, CF_Rule $rule): string
    {
        $str = [];

        $str[] = "FULL OUTER JOIN ($sql) q2 ON q2.hostkey = Hosts.HostKey";

        if ($joinInventory) {
            $str[] = 'LEFT JOIN inventory_new  ON Hosts.HostKey = inventory_new.hostkey';
        }

        $whereExists = false;
        if ($this->type !== self::ALL_TYPE) {
            $str[] = 'WHERE Hosts.HostKey ' . ($this->conditionMustBeMet ? 'NOT IN' : 'IN') . " ($sql)";
            $whereExists = true;
        }

        $filter = $rule->filterdata->filters->filter ?? [];
        $hostFilter = $rule->filterdata->filters->hostFilter ?? [];
        if (!empty($filter) || !empty($hostFilter)) {
            $jsonPayload = [
                'query' =>
                    'SELECT hostkey FROM hosts INNER JOIN inventory_cte ON inventory_cte.filtered_hostkey = hosts.hostkey',
                'filter' => $filter,
                'hostFilter' => $hostFilter,
            ];
            $filterParams = json_decode(json_encode($jsonPayload));
            $this->inventoryLib->extendSQLWithInventoryCTE($filterParams);
            $filterCondition = ($whereExists ? ' AND ' : ' WHERE ') . "Hosts.HostKey IN ({$filterParams->query})";
            $str[] = $filterCondition;
        }

        return implode(' ', $str);
    }

    /**
     * @return  void
     */
    protected function addResultColumn()
    {
        if ($this->type === self::ALL_TYPE) {
            if ($this->conditionMustBeMet) {
                $then = self::FAILING_TYPE;
                $else = self::PASSING_TYPE;
            } else {
                $then = self::PASSING_TYPE;
                $else = self::FAILING_TYPE;
            }
            array_unshift(
                $this->defaultColumns,
                "CASE WHEN q2.hostkey IS NULL THEN '$then' ELSE '$else' END AS \"Compliance\"",
            );
        } else {
            array_unshift($this->defaultColumns, "'$this->type' AS \"Compliance\"");
        }
    }
}
