<?php

# Request start time
define('BFF_NOW', microtime(true));

# Input data filters
define('TYPE_NOCLEAN', 0); # no changes
define('TYPE_BOOL', 1); # boolean
define('TYPE_INT', 2); # integer
define('TYPE_UINT', 3); # unsigned integer
define('TYPE_NUM', 4); # number
define('TYPE_UNUM', 5); # unsigned number
define('TYPE_UNIXTIME', 6); # unix datestamp (unsigned integer)
define('TYPE_STR', 7); # trimmed string
define('TYPE_NOTRIM', 8); # string - no trim
define('TYPE_NOHTML', 9); # trimmed string with HTML made safe
define('TYPE_ARRAY', 10); # array
define('TYPE_BINARY', 12); # binary string
define('TYPE_NOHTMLCOND', 13); # trimmed string with HTML made safe if determined to be unsafe
define('TYPE_NOTAGS', 14); # trimmed string, stripped tags
define('TYPE_DATE', 15); # date
define('TYPE_PRICE', 16); # price
define('TYPE_TEXT', 17); # plain text
define('TYPE_JSON', 18); # json (config only)
define('TYPE_PASS', 19); # password = string no trim

define('TYPE_ARRAY_NOCLEAN', 100);
define('TYPE_ARRAY_BOOL', 101);
define('TYPE_ARRAY_INT', 102);
define('TYPE_ARRAY_UINT', 103);
define('TYPE_ARRAY_NUM', 104);
define('TYPE_ARRAY_UNUM', 105);
define('TYPE_ARRAY_UNIXTIME', 106);
define('TYPE_ARRAY_STR', 107);
define('TYPE_ARRAY_NOTRIM', 108);
define('TYPE_ARRAY_NOHTML', 109);
define('TYPE_ARRAY_ARRAY', 110);
define('TYPE_ARRAY_BINARY', 112);
define('TYPE_ARRAY_NOHTMLCOND', 113);
define('TYPE_ARRAY_NOTAGS', 114);
define('TYPE_ARRAY_DATE', 115);
define('TYPE_ARRAY_PRICE', 116);
define('TYPE_ARRAY_TEXT', 117);

define('TYPE_CONVERT_SINGLE', 100); # value to subtract from array types to convert to single types
define('TYPE_CONVERT_KEYS', 200); # value to subtract from array => keys types to convert to single types

# Extensions types
define('EXTENSION_TYPE_PLUGIN', 1);
define('EXTENSION_TYPE_THEME', 2);
define('EXTENSION_TYPE_MODULE', 3);

/**
 * Get the available container instance.
 * @param string|null $abstract
 * @param array $parameters
 * @return mixed|\Application
 */
function bff($abstract = null, array $parameters = [])
{
    if (is_null($abstract)) {
        return bff::i();
    }

    return bff::i()->make($abstract, $parameters);
}

/**
 * File customization
 * @param string $filePath full file path
 * @param bool $customAllow allow customized file version: /custom/file
 * @return string customized file path
 */
function modification(string $filePath, bool $customAllow = true): string
{
    # Custom
    static $customDir;
    if (!isset($customDir)) {
        $customDir = PATH_BASE . 'custom' . DIRECTORY_SEPARATOR;
        if (!is_dir($customDir)) {
            $customDir = false;
        }
    }
    if ($customAllow && $customDir !== false) {
        # Custom
        $file = $customDir . substr($filePath, strlen(PATH_BASE));
        if (is_file($file)) {
            $filePath = $file;
        } elseif (mb_stripos($filePath, $customDir) === 0) {
            # Original
            $filePath = PATH_BASE . substr($filePath, strlen($customDir));
        }
    }
    return $filePath;
}

/**
 * Localize message
 * @param string $context message context
 * @param string $message message text
 * @param array|string|bool $params message parameters, language key (string), true - all languages, false - no translate return params as array
 * @param string|bool|null $language language key, null - current language, true - all languages, false - no translate return params as array
 * @param array $opts additional settings
 * @return string
 * @example _t('context', 'Date: [date]', array('date'=>date('Y.m.d'))); => Date 2001.01.01
 */
function _t(string $context, string $message, $params = [], $language = null, array $opts = [])
{
    return bff('locale')->translate($context, $message, $params, $language, $opts);
}

/**
 * Localize admin message
 * @param string $context message context
 * @param string $message message text
 * @param array|string|bool $params message parameters, language key (string), true - all languages
 * @param string|bool|null $language language key, null - current language, true - all languages
 * @param array $opts additional settings
 * @return string
 * @example _ta('context', 'Date: [date]', array('date'=>date('Y.m.d'))); => Date 2001.01.01
 */
function _ta(string $context, string $message, $params = [], $language = null, array $opts = [])
{
    return _t('@' . $context, $message, $params, $language, $opts);
}

/**
 * Localize message + escape
 * @param string $context message context
 * @param string $message message text
 * @param array|string|bool $params message parameters, language key (string), true - all languages
 * @param string|bool|null $language language key, null - current language, true - all languages
 * @param array $opts additional settings
 * @return string
 */
function _te(string $context, string $message, $params = [], $language = null, array $opts = [])
{
    return htmlspecialchars(_t($context, $message, $params, $language, $opts), ENT_QUOTES, 'UTF-8');
}

/**
 * Localize message + escape to use in javascript context
 * @param string $context message context
 * @param string $message message text
 * @param array|string|bool $params message parameters, language key (string), true - all languages
 * @param string|bool|null $language language key, null - current language, true - all languages
 * @param array $opts additional settings
 * @return string
 */
function _tejs(string $context, string $message, $params = [], $language = null, array $opts = [])
{
    return strtr(_t($context, $message, $params, $language, $opts), [
        '\\' => '\\\\',
        "'"  => "\\'",
        '"'  => '\\"',
        "\r" => '\\r',
        "\n" => '\\n',
        '</' => '<\/'
    ]);
}