<?php
require_once APPPATH . 'libraries/Cf_REST_Controller.php';
require_once APPPATH . 'models/Entities/CF_ComplianceScore.php';

class ComplianceReport extends Cf_REST_Controller
{
    public function __construct()
    {
        parent::__construct();

        if (CLI === true) {
            throw new Exception('ComplianceReport controller does not support CLI mode');
        }

        $this->username = $this->session->userdata('username') ?? ($this->restUser['id'] ?? null);
        $this->load->model('compliance_score');
        $this->load->model('advancedreports/compliance_exchange');
        $this->load->model('search_save_model');
        $this->compliance_exchange->setUsername($this->username);
    }

    public function score_post()
    {
        $score = new CF_ComplianceScore([
            'username' => $this->username,
            'report_id' => $this->input->post('report_id'),
            'fail_checks' => $this->input->post('fail_checks'),
            'score' => $this->input->post('score'),
            'total' => $this->input->post('total'),
        ]);

        $this->compliance_score->setScore($score);
        $this->respond_ok();
    }

    public function score_get()
    {
        $result = [];
        foreach ($this->compliance_score->getScore($this->input->get('ids'), $this->username) as $item) {
            $result[$item['report_id']] = $item;
        }
        $this->respond_ok(json_encode($result));
    }

    /**
     * Create new compliance report with default name and redirect to the edit report page
     * If a report with the same name exists, it should add the next available number
     */
    public function create_report_get()
    {
        $this->load->model('search_save_model');
        $defaultName = 'New Compliance Report';
        try {
            // get report to identify next available ID
            $report = $this->search_save_model->get_all_search(
                $filter = ['label ~' => "$defaultName(\s\d+)"],
                $offset = 0,
                $limit = 1,
                $order = 'regexp_replace(label, \'\D\', \'\', \'g\')::int DESC',
            );

            $existingLabel = $report[0]->label ?? '';
            $name = $defaultName . ' ' . (intval(preg_replace('/[^0-9]/', '', $existingLabel)) + 1);

            $data = [
                'username' => $this->username,
                'url' => 'advancedreports',
                'reportType' => 'Advanced reports',
                'type' => 'compliance',
                'params' => '',
                'label' => $name,
                'reportCategory' => 'compliance_report',
                'date' => time(),
                'is_public' => 0,
            ];

            $obj = $this->search_save_model->insert($data, false, isActionAllowed('reports.admin'));
            redirect("/reports/compliance/edit/{$obj->id}", 'refresh');
        } catch (Exception $e) {
            log_message(
                log_level_for_exception($e),
                'Unexpected error while performing compliance report creating. ' . $e->getTraceAsString(),
            );
            // redirect to the page where a user can manually set the report name and save it in case of error
            redirect('/reports/compliance/add_report', 'refresh');
        }
    }

    public function import_post()
    {
        $response = $this->compliance_exchange->import($this->input->post());
        if (!isset($response['duplicates'])) {
            $this->respond_ok(json_encode($response, JSON_PRETTY_PRINT));
        } else {
            $response['message'] =
                'There are already different reports or conditions with the same name, please rename or delete it before importing';
            $this->respond_not_acceptable(json_encode($response, JSON_PRETTY_PRINT));
        }
    }

    public function export_get()
    {
        $id = intval($this->input->get('id'));

        if (sizeof($this->search_save_model->get_all_search(['id' => $id, 'type' => 'compliance'])) == 0) {
            $this->respond_not_found("Compliance report #$id not found");
            exit();
        }

        if (!($file = $this->compliance_exchange->export($id))) {
            $this->respond_internal_error('Cannot read the export file');
            exit();
        }

        $content = file_get_contents(get_tmpdir() . $file);
        $this->respond_ok($content);
    }
}
