<?php

/**
 * Class MailSettingsModel
 */
class MailSettingsModel extends CI_Model
{
    /**
     * @var array
     */
    private $allowedKeys = [
        'protocol',
        'mailpath',
        'smtp_host',
        'smtp_user',
        'smtp_pass',
        'smtp_port',
        'default_from_email',
        'max_email_attach_size',
        'smtp_crypto',
        'email_link_domain',
    ];

    /**
     * @var array Allowed directories for mailpath
     */
    public $allowedMailpathDirs = [
        '/usr/sbin',
        '/usr/bin',
        '/usr/lib',
        '/bin',
        '/sbin',
        '/usr/local/sbin',
        '/usr/local/bin',
        '/opt/local/sbin',
        '/opt/local/bin',
    ];

    /**
     * MailSettingsModel constructor.
     */
    public function __construct()
    {
        parent::__construct();
    }

    /**
     * @return array
     */
    public function getSettings()
    {
        $query = $this->db->get('mail_settings;');
        $settings = $query->result();
        $data = [];
        foreach ($settings as $setting) {
            $data[trim($setting->key)] = $setting->value;
        }
        return $data;
    }

    /**
     * @return array
     */
    public function getSetting($key)
    {
        $query = $this->db->where('key', $key)->get('mail_settings');
        $setting = $query->row();
        if ($setting && isset($setting->value)) {
            return $setting->value;
        }
        return false;
    }

    /**
     * @param $data
     * @return bool
     */
    public function updateSettings($data)
    {
        foreach ($data as $key => $value) {
            if (!in_array($key, $this->allowedKeys)) {
                unset($data[$key]);
                continue;
            }
            $this->db->set('value', $value);
            $this->db->where('key', $key);
            $this->db->update('mail_settings');
        }

        return true;
    }

    public function isSettingsTableExists()
    {
        $isExists = $this->db
            ->query(
                '
        SELECT EXISTS (
                SELECT 1
                FROM   information_schema.tables
                WHERE  table_schema = \'public\'
                AND    table_name = \'mail_settings\'
                                          )',
            )
            ->row();

        return $isExists->exists;
    }

    /**
     * Validates that the mailpath is within an allowed directory.
     *
     * @param string $mailpath The mailpath to validate
     * @return bool True if valid, false otherwise
     */
    public function validateMailpath($mailpath)
    {
        if (empty($mailpath)) {
            return true;
        }

        // The file must exist to validate its real path
        $realpath = realpath($mailpath);
        if ($realpath === false) {
            return false;
        }

        $dir = dirname($realpath);
        return in_array($dir, $this->allowedMailpathDirs, true);
    }
}
