<?php

/**
 * Generates HTML table from JSON data structure for report generation
 */
class cfe_table
{
    public $dateTimeFields = [];
    public $ignoreDateColor = [];
    public $template = [
        'table_open' => '<table class="table table-striped table-bordered table-condensed">',
        'thead_open' => '<thead>',
        'thead_close' => '</thead>',
        'heading_row_start' => '<tr>',
        'heading_row_end' => '</tr>',
        'heading_cell_start' => '<th>',
        'heading_cell_end' => '</th>',
        'tbody_open' => '<tbody>',
        'tbody_close' => '</tbody>',
        'row_start' => '<tr>',
        'row_end' => '</tr>',
        'cell_start' => '<td>',
        'cell_end' => '</td>',
        'row_alt_start' => '<tr>',
        'row_alt_end' => '</tr>',
        'cell_alt_start' => '<td>',
        'cell_alt_end' => '</td>',
        'table_close' => '</table>',
    ];

    public function __construct()
    {
        $this->CI = &get_instance();
        $this->CI->load->library('table');
        $this->CI->table->set_template($this->template);

        // these array are the report titles where date should not be coloured
        $this->ignoreDateColor = [
            'Promises not kept log',
            'Promises repaired log',
            'Compliance summary',
            'File change log',
            'File change diffs',
            'Performance',
        ];

        // these are the table fields that should be formatted as date and time
        $this->dateTimeField = [
            'lastseen',
            'last seen',
            'time',
            'last verified',
            'change detected at',
            'last performed',
            'last occurred',
            'was last seen at',
            'last occured',
        ];
    }

    public function generateHeadings($header, $hideColumns = [])
    {
        $heading = '<tr>';
        foreach ($header as $title) {
            if (in_array(strtolower($title), $hideColumns)) {
                continue;
            }
            $heading .= '<th>' . $title . '</th>';
        }
        $heading .= '</tr>';
        return $heading;
    }

    public function generateRows($row)
    {
        if (!is_array($row)) {
            $rowArray['data'] = $row;
        } else {
            $rowArray = $row;
        }

        $tr = '<tr>';
        $attributes = '';
        foreach ($rowArray as $td) {
            if (is_array($td) && array_key_exists('data', $td)) {
                $value = $td['data'];
                foreach ($td as $key => $val) {
                    if ($key != 'data') {
                        $attributes .= sprintf('%s="%s" ', $key, $val);
                    }
                }
            } else {
                $value = $td;
            }

            $tr .= sprintf('<td %s>%s</td>', $attributes, $value);
        }
        $tr .= '</tr>';
        return $tr;
    }

    public function generateSqlTables($result, $report_title = null, $hideColumns = [])
    {
        $return = '';
        if (is_array($result)) {
            $tableHeader = $this->generateHeadings($result['meta']['header'], $hideColumns);
            $tableBody = '';
            if (count($result['data']) > 0) {
                foreach ($result['data'] as $key => $row) {
                    $temp = [];
                    foreach ($row as $index => $value) {
                        $header = $result['meta']['header'][$index];
                        if (in_array(strtolower($header), $hideColumns)) {
                            continue;
                        }
                        $tempValue = $this->_formatValue($report_title, $header, $value);
                        array_push($temp, $tempValue);
                    }
                    $tableBody .= $this->generateRows($temp);
                }
            }
            $return = sprintf(
                '<table class="table table-striped table-bordered table-condensed table-hover"><thead>%s</thead><tbody>%s</tbody></table>',
                $tableHeader,
                $tableBody,
            );
        }
        return $return;
    }

    public function _formatValue($report_title, $header, $value)
    {
        $tempValue = $value;
        if (in_array(strtolower($header), $this->dateTimeField)) {
            $color = in_array(trim($report_title), $this->ignoreDateColor);
            $tempValue = getDateStatus($value, $color);
        }
        if (strtolower($header) == 'promise handle') {
            $url = sprintf(
                '<a target="_self" href="%s/policies/index/handle/%s">%s</a>',
                site_url(),
                urlencode($tempValue),
                $tempValue,
            );
            $tempValue = generateLink('policies', $url, $tempValue);
        } elseif (strtolower($header) == 'bundle') {
            $url = sprintf(
                '<a target="_self" href="%s/policies/index/bundle/%s">%s</a>',
                site_url(),
                urlencode($tempValue),
                $tempValue,
            );
            $tempValue = generateLink('policies', $url, $tempValue);
        }
        return $tempValue;
    }

    /**
     * Optimized for less memory usage, doesnt uses CI table generator
     * @param type $result
     * @param type $report_title
     * @return type
     */
    public function generateReportTableModified($result, $report_title = '', $hideColumns = [])
    {
        $return = '';
        if (is_array($result)) {
            $tableHeader = $this->generateHeadings(array_keys($result['meta']['header']), $hideColumns);
            $tableBody = '';
            $heading = '';
            if (count($result['data']) > 0) {
                foreach ($result['data'] as $row) {
                    $temp = [];
                    foreach ($result['meta']['header'] as $key => $value) {
                        if (!is_array($value)) {
                            if (in_array(strtolower($key), $hideColumns)) {
                                continue;
                            }
                            if (in_array(strtolower($key), $this->dateTimeField)) {
                                $color = in_array(trim($report_title), $this->ignoreDateColor);
                                array_push($temp, getDateStatus($row[$value], $color));
                            } else {
                                $tempValue = $row[$value];
                                // make link to bundle and promises
                                if (strtolower($key) == 'promise handle') {
                                    $url = sprintf(
                                        '<a target="_self" href="%s/policies/index/handle/%s">%s</a>',
                                        site_url(),
                                        urlencode($tempValue),
                                        $tempValue,
                                    );
                                    $tempValue = generateLink('policies', $url, $tempValue);
                                } elseif (strtolower($key) == 'bundle') {
                                    $url = sprintf(
                                        '<a target="_self" href="%s/policies/index/bundle/%s">%s</a>',
                                        site_url(),
                                        urlencode($tempValue),
                                        $tempValue,
                                    );
                                    $tempValue = generateLink('policies', $url, $tempValue);
                                } elseif (strtolower($key) == 'virtual bundle') {
                                    $tempValue = sprintf(
                                        '<a target="_self" href="%s/virtualbundle/details/%s">%s</a>',
                                        site_url(),
                                        trim(urlencode($tempValue)),
                                        $tempValue,
                                    );
                                }

                                array_push($temp, $tempValue);
                            }
                        } else {
                            if (strtolower($key) == 'note') {
                                $link = site_url('notes') . '/index/';
                                $data_index = $value['index'];
                                $notesAlreadyPresent = false;
                                foreach ($value['subkeys'] as $subkey => $subval) {
                                    $data = trim($row[$data_index][$subval]);

                                    if ($subkey == 'rid') {
                                        $data = urlencode(mb_convert_encoding($data, 'UTF-8'));
                                    }
                                    if ($data != '') {
                                        $link .= "$subkey/$data/";
                                        // if subval action is show we can indicate it visually there are some comments
                                        if ($subkey == 'action' && $data == 'show') {
                                            $notesAlreadyPresent = true;
                                        }
                                    }
                                }
                                $addClass = $notesAlreadyPresent ? 'notes-highlight' : '';
                                $c = [
                                    'data' => anchor($link, 'notes', ['class' => 'note']),
                                    'class' => $addClass,
                                ];
                                array_push($temp, $c);
                            }
                        }
                    }
                    //$this->CI->table->add_row($temp);
                    $tableBody .= $this->generateRows($temp);
                }
            }
            $return = sprintf(
                '<table class="table table-striped table-bordered table-condensed table-hover"><thead>%s</thead><tbody>%s</tbody></table>',
                $tableHeader,
                $tableBody,
            );
        }
        return $return;
    }

    public function host_only_table($data)
    {
        $this->CI->table->set_heading('hostname', 'IP', 'key', 'Action');

        foreach ((array) $data['data'] as $rows) {
            $lnk = anchor(
                'search/index/report/promises-not-kept-summary/to/0/from/0/host/' . $rows['hostkey'],
                'list all promises not kept',
                ['title' => 'promises not kept', 'class' => '', 'rel' => 'tooltip'],
            );

            $cell = ['data' => $lnk, 'class' => 'actioncol'];
            $this->CI->table->add_row([
                anchor('hosts/' . $rows['hostkey'], $rows['hostname'], 'class=""'),
                $rows['ip'],
                $rows['hostkey'],
                $cell,
            ]);
        }
        return $this->CI->table->generate();
    }
}
