<?php

class SettingsHelper
{
    public const PASSWORD_COMPLEXITY = 'passwordComplexity';
    public const MIN_PASSWORD_LENGTH = 'minPasswordLength';
    public const PASSWORD_EXPIRATION_AFTER_RESET_HOURS = 'passwordExpirationAfterResetHours';
    public const ENFORCE_2FA = 'enforce2FA';
    public const ALLOW_LLM_VIEW_ACCESS_TO_ATTRIBUTES_NAMES = 'allowLlmViewAccessToAttributesNames';
    public const DISABLE_AI = 'disableAI';
    public const DELETED_HOSTS_CLEANUP = 'deletedHostsCleanup';
    public const DUPLICATE_HOSTNAME_HOSTS_CLEANUP = 'duplicateHostnameHostsCleanup';
    public const DUPLICATE_IP_HOSTS_CLEANUP = 'duplicateIpHostsCleanup';
    public const GROUP_HOSTS_CLEANUP = 'groupHostsCleanup';
    public const INACTIVE_HOSTS_CLEANUP = 'inactiveHostsCleanup';

    public const INTEGERS = [
        self::PASSWORD_COMPLEXITY,
        self::MIN_PASSWORD_LENGTH,
        self::PASSWORD_EXPIRATION_AFTER_RESET_HOURS
    ];

    public const BOOLEANS = [
        self::ENFORCE_2FA,
        self::ALLOW_LLM_VIEW_ACCESS_TO_ATTRIBUTES_NAMES,
        self::DISABLE_AI,
    ];

    public const JSON_OBJECTS = [
        self::DELETED_HOSTS_CLEANUP,
        self::DUPLICATE_HOSTNAME_HOSTS_CLEANUP,
        self::DUPLICATE_IP_HOSTS_CLEANUP,
        self::GROUP_HOSTS_CLEANUP,
        self::INACTIVE_HOSTS_CLEANUP,
    ];

    public const DEFAULTS = [
        self::PASSWORD_COMPLEXITY => 3,
        self::MIN_PASSWORD_LENGTH => 8,
        self::PASSWORD_EXPIRATION_AFTER_RESET_HOURS => 48,
        self::DELETED_HOSTS_CLEANUP => ['enabled' => false, 'days' => 90],
        self::DUPLICATE_HOSTNAME_HOSTS_CLEANUP => ['enabled' => false, 'completelyClear' => false],
        self::DUPLICATE_IP_HOSTS_CLEANUP => ['enabled' => false, 'completelyClear' => false],
        self::GROUP_HOSTS_CLEANUP => ['enabled' => false, 'groupId' => null, 'completelyClear' => false],
        self::INACTIVE_HOSTS_CLEANUP => ['enabled' => false, 'days' => 30, 'completelyClear' => false],
    ];

    /** @var array */
    protected static $allowedSettings = [
        'rbacEnabled',
        'ldapEnabled',
        'hostIdentifier',
        'blueHostHorizon',
        'hostsCollisionsThreshold',
        'passwordComplexity',
        'minPasswordLength',
        'passwordExpirationAfterResetHours',
        'enforce2FA',
        'logLevel',
        'ldap_enable_role_syncing',
        'ldap_roles_list_to_sync',
        'ldap_perform_sync_on_login',
        'ldap_remove_role_on_syncing',
        self::ALLOW_LLM_VIEW_ACCESS_TO_ATTRIBUTES_NAMES,
        self::DISABLE_AI,
        self::DELETED_HOSTS_CLEANUP,
        self::DUPLICATE_HOSTNAME_HOSTS_CLEANUP,
        self::DUPLICATE_IP_HOSTS_CLEANUP,
        self::GROUP_HOSTS_CLEANUP,
        self::INACTIVE_HOSTS_CLEANUP,
    ];

    /**
     * Remove LDAP Password from settings
     *
     * @param $settings
     * @return string
     */
    public static function removeLdapPassword($settings)
    {
        if (is_string($settings)) {
            $settings = json_decode($settings);
            if (isset($settings->data) && isset($settings->data[0]) && isset($settings->data[0]->ldapPassword)) {
                unset($settings->data[0]->ldapPassword);
            }
        }
        return json_encode($settings, JSON_PRETTY_PRINT);
    }

    /**
     * Remove not allowed settings
     *
     * @param $data
     */
    public static function removeUnAllowedSettings(&$data)
    {
        foreach ($data as $key => $value) {
            if (! in_array($key, self::$allowedSettings)) {
                unset($data[ $key ]);
            }
        }
    }

    /**
     * Stringify object-valued settings to JSON strings before passing to the C API
     *
     * @param array $settings
     */
    public static function encodeJsonObjectSettings(array &$settings): void
    {
        foreach (self::JSON_OBJECTS as $key) {
            if (array_key_exists($key, $settings) && !is_string($settings[$key])) {
                $settings[$key] = json_encode($settings[$key]);
            }
        }
    }

    /**
     * Decode JSON-string settings coming from the C API back into objects/arrays
     *
     * @param string $settings  raw JSON response from cfapi_settings_get
     * @return string
     */
    public static function decodeJsonObjectSettings(string $settings): string
    {
        $decoded = json_decode($settings, true);
        if (!is_array($decoded['data'][0] ?? null)) {
            return $settings;
        }
        foreach (self::JSON_OBJECTS as $key) {
            if (isset($decoded['data'][0][$key]) && is_string($decoded['data'][0][$key])) {
                $value = json_decode($decoded['data'][0][$key], true);
                if (is_array($value)) {
                    $decoded['data'][0][$key] = $value;
                }
            }
        }
        return json_encode($decoded, JSON_PRETTY_PRINT);
    }
}
