<?php
class apps extends Cf_Controller
{
    public function __construct()
    {
        parent::__construct();
        $this->iconsPath = realpath(
            APPPATH . '..' . DIRECTORY_SEPARATOR . 'images' . DIRECTORY_SEPARATOR . 'icons' . DIRECTORY_SEPARATOR,
        );
    }

    /**
     * Show all installed applications
     *
     * @rbacName View application list
     * @rbacGroup Application management
     * @rbacAlias apps.index
     */
    public function index()
    {
        $applications = $this->apps_model->getAllApplication();

        $data = [
            'title' => $this->lang->line('mission_portal_title') . ' - ' . $this->lang->line('applications'),
            'applications' => $applications,
        ];

        $this->template->load('template', 'apps/index', $data);
    }

    /**
     *  Save frontend settings for applications - order and enable/disable
     *
     * @rbacName Save application settings
     * @rbacDescription change order and enable/disable
     * @rbacGroup Application management
     * @rbacAlias apps.save
     */
    public function save()
    {
        $apps = $this->input->post('apps');

        if (!empty($apps)) {
            foreach ($apps as $item => $app) {
                $data = [];
                $data['id'] = $item;

                // only if integer number, otherwice keep old value
                $tmp_int = (int) $app['displayindex'];
                $tmp_str = (string) $tmp_int;

                if ($tmp_str === $app['displayindex']) {
                    $data['displayindex'] = $tmp_int;
                }
                $data['state'] = intval($app['state'], 10);

                $this->apps_model->updateApp($data);
            }

            $this->session->set_flashdata('message', ['content' => 'Applications updated', 'type' => 'alert-success']);
            redirect('apps/index');
        }
    }

    /**
     * View information about application
     * @param <string> $appid - application id
     */
    public function view($appid)
    {
        $application = $this->_check_if_exist($appid);

        $data = [
            'title' => $this->lang->line('mission_portal_title') . ' - ' . $this->lang->line('applications'),
            'application' => $application,
        ];

        $this->load->view('apps/view', $data);
    }

    /**
     * Check for new application, copy icons etc
     *
     * @rbacName Refresh app list
     * @rbacGroup Application management
     * @rbacAlias apps.apprefresh
     *
     */
    public function apprefresh()
    {
        $this->load->helper('directory');

        $apps = $this->apps_model->getAllApplication();

        // create new array where app id is a key
        foreach ($apps as $item => $app) {
            $installedApps[$app['id']] = $app; //app id = module folder name
        }

        // loop throught modules and try to find meta.json file and update DB information
        $modules = [];
        foreach (Modules::$locations as $location => $offset) {
            // get modules
            if (is_dir($source = $location)) {
                $modules = directory_map($location, 1);
            }

            if (count($modules)) {
                // tring to find meta info
                foreach ($modules as $item => $module) {
                    $metaData = [];
                    $icon = '';
                    $source = $location . $module . DIRECTORY_SEPARATOR;
                    $metaFile = $source . 'config' . DIRECTORY_SEPARATOR . 'meta.json';

                    // trying to get meta data from meta.xml
                    if (is_file($metaFile)) {
                        $metaData = $this->apps_model->getAppsMetaData($metaFile, $module);

                        //check icon file
                        $iconFile =
                            $source . DIRECTORY_SEPARATOR . 'html' . DIRECTORY_SEPARATOR . ($metaData['icon'] ?? '');
                        if (is_file($iconFile)) {
                            $ext = pathinfo($iconFile, PATHINFO_EXTENSION);
                            $newFileName = $module . '.' . $ext; //set icon name as module name

                            //copy icon to the images/icons folder
                            //1.delete old icon
                            @unlink($this->iconsPath . DIRECTORY_SEPARATOR . $newFileName);

                            //copy new icon
                            if (@copy(realpath($iconFile), $this->iconsPath . DIRECTORY_SEPARATOR . $newFileName)) {
                                $icon = $newFileName;
                            }
                        }
                    }

                    //set default data if empty
                    if (empty($metaData)) {
                        $metaData = $this->apps_model->setAppsDefaultMeta($module);
                    }

                    //prepare data to insert or update
                    $dbData = [];
                    $module = str_replace('/', '', $module);
                    $dbData['id'] = $module; //equal to folder name
                    $dbData['url'] = isset($metaData['url']) ? $metaData['url'] : urlencode($module);
                    $dbData['rbac_id'] = isset($metaData['rbac_id']) ? $metaData['rbac_id'] : null;

                    //if no display index - show it as last app
                    $dbData['displayindex'] = !empty($installedApps[$module]['displayindex'])
                        ? $installedApps[$module]['displayindex']
                        : '9999';
                    $dbData['state'] = !empty($installedApps[$module]['state']) ? 1 : 0; // off by default

                    $dbData['meta'] = $metaData;
                    $dbData['filepath'] = $source; // physical path in filesystem (from approot)

                    $dbData['icon'] = !empty($icon) ? $icon : 'default.png';

                    $dbData['showappslist'] = !empty($metaData['show_apps_list']) ? 1 : false;
                    $dbData['hascontroller'] = !empty($metaData['has_controller']) ? 1 : false;

                    $this->apps_model->updateApp($dbData);
                }
            }
        }
        $err = $this->apps_model->getErrors();

        if (!empty($err)) {
            $this->session->set_flashdata('message', ['content' => implode(' ', $err), 'type' => 'alert-error']);
        } else {
            $this->session->set_flashdata('message', ['content' => 'Applications updated', 'type' => 'alert-success']);
        }

        redirect('apps/index');
    }

    /**
     * Check if application exist
     *
     *
     * @param <string> $appid - application id
     * @return <array> application data
     */
    public function _check_if_exist($appid)
    {
        if ($appid == '') {
            redirect('apps/index');
        }

        $application = $this->apps_model->getApplication($appid);

        if (empty($application)) {
            $this->session->set_flashdata('message', [
                'content' => "Application: <b>$appid</b> not found",
                'type' => 'alert-error',
            ]);
            redirect('apps/index');
        }

        return $application;
    }
}
