<?php

class Host_generate_model extends Cf_Model
{
    public $nokeptCount;
    public $hostCount = 1;
    public $withSoftware = 0;
    public $interval = 60;
    public $verbose = false;
    public $hostKey;
    protected $cfdb;

    protected $n = 2;

    public function setDb($db)
    {
        $this->cfdb = $db;
        $this->cfdb->save_queries = false;
    }

    public function generateHost($hostKey)
    {
        $sql =
            'INSERT INTO "__hosts" ("hostkey", "ipaddress", "iscallcollected", "lastreporttimestamp", "firstreporttimestamp") VALUES (\'%s\', \'1.2.3.4\', \'false\', \'now()\', \'now()\');';
        $sql = sprintf($sql, $hostKey);
        $this->cfdb->query($sql);
    }

    public function generateHosts($hostKey, $count)
    {
        $sql =
            'INSERT INTO "__hosts" ("hostkey", "ipaddress", "iscallcollected", "lastreporttimestamp", "firstreporttimestamp") VALUES ';
        for ($i = 1; $i <= $count; $i++) {
            $nextHostkey = $hostKey . $i;

            $nextIpAddr = '';
            for ($j = 0; $j < 4; $j++) {
                if ($j > 0) {
                    $nextIpAddr = '.' . $nextIpAddr;
                }
                $nextIpAddr = intdiv($i, 256 ** $j) % 256 . $nextIpAddr;
            }

            $sql .= "('$nextHostkey', '$nextIpAddr', 'false', 'now()', 'now()')";
            if ($i != $count) {
                $sql .= ',';
            }
        }
        $this->cfdb->query($sql);
    }

    public function generateLastSeenHosts($hostKey, $count)
    {
        $sql =
            'INSERT INTO "%s" ("hostkey", "compo", "lastseendirection", "remotehostkey", "remotehostip", "lastseentimestamp", "lastseeninterval") VALUES ';
        for ($i = 1; $i <= $count; $i++) {
            $nextHostkey = $hostKey . $i;
            $ip = mt_rand(1, 255) . '.' . mt_rand(1, 255) . '.' . mt_rand(1, 255) . '.' . mt_rand(1, 255);
            $sql .= "('$nextHostkey', 'INCOMING.$nextHostkey', 'INCOMING', '$nextHostkey', '$ip', 'now()', '300')";
            if ($i != $count) {
                $sql .= ',';
            }
        }
        $this->cfdb->query(sprintf($sql, '__lastseenhosts'));
    }

    public function generateVariables($hostKey)
    {
        $data = include __DIR__ . '/../data/variables.php';
        $sql =
            'INSERT INTO "__variables" ("hostkey", "namespace", "bundle", "variablename", "variablevalue", "variabletype", "comp", "metatags", "changetimestamp") VALUES ';
        foreach ($data as $key => $d) {
            $sql .= vsprintf("('%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s')", $d);
            if (isset($data[$key + 1])) {
                $sql .= ',';
            }
        }
        $this->cfdb->query($sql);
    }

    public function generateSoftware($hostKey)
    {
        $sql = file_get_contents(__DIR__ . '/../data/software.sql');
        $sql = str_replace('%hostkey%', $hostKey, $sql);
        $sql = str_replace('%timestamp%', date('Y-m-d H:i:s+00'), $sql);
        $this->cfdb->query($sql);

        $sql = file_get_contents(__DIR__ . '/../data/softwareupdates.sql');
        $sql = str_replace('%hostkey%', $hostKey, $sql);
        $sql = str_replace('%timestamp%', date('Y-m-d H:i:s+00'), $sql);
        $this->cfdb->query($sql);
    }

    public function generateCMDB($hostKey, $epoch)
    {
        $sql = file_get_contents(__DIR__ . '/../data/cmdb.sql');
        $sql = str_replace('%hostkey%', $hostKey . $epoch, $sql);
        $sql = str_replace('%timestamp%', date('Y-m-d H:i:s+00'), $sql);
        $sql = str_replace('%epoch%', $epoch, $sql);
        $this->cfdb->query($sql);
    }

    public function generatePromiseExecutions($hostKey)
    {
        $sql = file_get_contents(__DIR__ . '/../data/promiseexecutions.sql');
        $sql = str_replace('%hostkey%', $hostKey, $sql);
        $sql = str_replace('%timestamp%', date('Y-m-d H:i:s+00'), $sql);
        $this->cfdb->query($sql);
    }

    public function generatePromiseLog($hostKey)
    {
        $sql = file_get_contents(__DIR__ . '/../data/promiselog.sql');
        $sql = str_replace('%hostkey%', $hostKey, $sql);
        $sql = str_replace('%timestamp%', date('Y-m-d H:i:s+00'), $sql);
        $this->cfdb->query($sql);
    }

    public function generateContexts($hostKey)
    {
        $data = include __DIR__ . '/../data/contexts.php';
        $sql = 'INSERT INTO "__contexts" ("hostkey", "contextname", "metatags", "changetimestamp")  VALUES ';
        foreach ($data as $key => $d) {
            $sql .= vsprintf("('%s', '%s', '%s', '%s')", $d);
            if (isset($data[$key + 1])) {
                $sql .= ',';
            }
        }
        $this->cfdb->query($sql);
    }

    public function bulkGenerateContexts($hostKeyPattern, $count)
    {
        $sql = 'INSERT INTO "__contexts" ("hostkey", "contextname", "metatags", "changetimestamp")  VALUES ';
        for ($i = 1; $i <= $count; $i++) {
            $hostKey = $hostKeyPattern . $i;
            $data = include __DIR__ . '/../data/contexts.php';
            foreach ($data as $key => $d) {
                $sql .= vsprintf("('%s', '%s', '%s', '%s')", $d);
                if ($i != $count || isset($data[$key + 1])) {
                    $sql .= ',';
                }
            }
        }
        $this->cfdb->query($sql);
    }

    public function bulkGenerateVariables($hostKeyPattern, $count)
    {
        $initialSql = $sql =
            'INSERT INTO "__variables" ("hostkey", "namespace", "bundle", "variablename", "variablevalue", "variabletype", "comp", "metatags", "changetimestamp") VALUES ';
        for ($i = 1; $i <= $count; $i++) {
            $hostKey = $hostKeyPattern . $i;
            $data = include __DIR__ . '/../data/variables.php';
            foreach ($data as $key => $d) {
                $sql .= vsprintf("('%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s')", $d);
                $sql .= ',';
            }

            if ($i % 500 == 0) {
                $sql = trim($sql, ',');
                $this->cfdb->query($sql);
                $sql = $initialSql;
            }
        }

        if ($count % 500 != 0) {
            $sql = trim($sql, ',');
            $this->cfdb->query($sql);
        }
    }

    public function updateContextCache()
    {
        $this->cfdb->query('TRUNCATE TABLE ContextCache;');
        $this->cfdb->query('INSERT INTO ContextCache (hostkey, contextvector)
    SELECT hostkey, to_tsvector(\'simple\', replace(x::text,\'_\',\'.\'))
    FROM (
        SELECT hostkey, array_agg(contextname) as x
        FROM __Contexts
        GROUP BY hostkey
        ) as sub;');
    }

    public function updateMaterializedViews()
    {
        $this->cfdb->query('CALL update_inventory();');
    }

    public function generateAgentStatus($hostKey, $status)
    {
        $this->cfdb->query(
            "INSERT INTO __agentstatus (hostkey, agentexecutioninterval, lastagentlocalexecutiontimestamp, lastagentexecutionstatus) VALUES
                          ('$hostKey', 300,	now(), '" .
                $status .
                "');",
        );
    }

    public function bulkGenerateAgentStatus($hostKeyPattern, $count, $failCount)
    {
        $sql =
            'INSERT INTO __agentstatus (hostkey, agentexecutioninterval, lastagentlocalexecutiontimestamp, lastagentexecutionstatus) VALUES ';
        for ($i = 1; $i <= $count; $i++) {
            $hostKey = $hostKeyPattern . $i;
            $status = $i > $failCount ? 'OK' : 'FAIL';
            $sql .= "('$hostKey', 300,	now(), '" . $status . "'),";
        }
        $sql = trim($sql, ',');
        $this->cfdb->query($sql);
    }

    public function setNotKept($hostKey, $i)
    {
        if ($i == $this->n) {
            $this->n += 5;
        } else {
            return false;
        }

        $sql = <<<SQL
                INSERT INTO "__promiseexecutions" ("hostkey", "policyfile", "releaseid", "promisehash", "namespace", "bundlename", "promisetype", "promiser", "stackpath", "promisehandle", "promiseoutcome", "logmessages", "promisees", "changetimestamp")
                VALUES ('%s', 'file.sh', NULL, 'promisehash', 'default', 'cfe_internal_enterprise_main', 'methods', NULL, 'cfe_internal_enterprise_main', NULL, 'NOTKEPT', NULL, NULL, NULL);
        SQL;
        $this->cfdb->query(sprintf($sql, $hostKey));
    }

    public function generateMeasurementsData($hostKey)
    {
        $this
            ->cfdb->query("INSERT INTO __monitoringmgmeta (hostkey, observable, global, expected_min, expected_max, unit, description, updatedtimestamp) VALUES
                          ('$hostKey',	'cpu',	'1',	0,	100,	'percent',	'%CPU utilization (all)',	now());");

        $id = $this->cfdb->insert_id();

        $this
            ->cfdb->query("INSERT INTO \"__monitoringmg\" (\"meta_id\", \"sample\", \"value1\", \"value2\", \"value3\", \"value4\", \"updatedtimestamp\") VALUES
                           ($id,	1, 10.1,	7.35,	7.7,	0,	now() + '5 minutes'::interval),
                           ($id,	2, 1.34,	3.01,	5.58,	0,	now() + '10 minutes'::interval),
                           ($id,	3, 1.39,	3.06,	5.58,	0,	now() + '15 minutes'::interval),
                           ($id,	4, 9.8 ,	7.14,	7.45,	0,	now() + '20 minutes'::interval),
                           ($id,	5, 9.85,	7.16,	7.53,	0,	now() + '25 minutes'::interval),
                           ($id,	6, 1.41,	3.05,	5.45,	0,	now() + '30 minutes'::interval);");
    }
}
