<?php

// +-------------------------------------------------+
// ï¿½ 2002-2004 PMB Services / www.sigb.net pmb@sigb.net et contributeurs (voir www.sigb.net)
// +-------------------------------------------------+
// $Id: CertificateModel.php,v 1.3.8.3 2026/01/22 09:12:29 qvarin Exp $

namespace Pmb\Digitalsignature\Models;

use encoding_normalize;
use Pmb\Common\Library\Crypto\Crypto;
use Pmb\Digitalsignature\Orm\CertificateOrm;
use Pmb\Common\Models\Model;
use Pmb\Digitalsignature\Orm\SignatureOrm;

class CertificateModel extends Model
{

    /**
     * Champs sensibles à offusquer
     */
    private const SENSITIVE_FIELDS = ['token', 'privateKey', 'cert', 'url'];

    /**
     * Paramètres du certificat
     */
    public $settings;

    /**
     * Nom de la classe ORM
     */
    protected $ormName = "\Pmb\Digitalsignature\Orm\CertificateOrm";

    public const CERTIFICATE_MODE_API = 0;

    public const CERTIFICATE_MODE_LOCAL = 1;

    /**
     * Récupération de la liste des certificats
     *
     * @return array
     */
    public static function getCertificateList()
    {
        $list = CertificateOrm::findAll();
        $returnCertificates = [];
        $defaultSettings = (object) ['name' => '', 'mode' => '0', 'url' => '', 'token' => '', 'cert' => '', 'privateKey' => ''];

        foreach ($list as $certificate) {
            $decoded = encoding_normalize::json_decode($certificate->settings ?? '{}');
            $settings = self::deOffuscateSettings($decoded);

            $cert = new \stdClass();
            $cert->id = $certificate->id;
            $cert->settings = $settings ?? $defaultSettings;
            $returnCertificates[] = $cert;
        }

        return $returnCertificates;
    }

    /**
     * Mise à jour d'un certificat
     *
     * @param object $data
     * @return void
     */
    public static function updateCertificate($data)
    {
        $certificate = new CertificateOrm(intval($data->id));
        $certificate->settings = self::offuscateSettings($data);
        $certificate->save();
    }

    /**
     * Suppression d'un certificat
     *
     * @param int $id
     * @return void
     */
    public static function deleteCertificate($id)
    {
        global $msg;
        $certificate = new CertificateOrm(intval($id));
        $tab = SignatureOrm::find("num_cert", $id);
        if (count($tab)) {
            return error_message($msg["admin_certifate_error"], $msg["admin_certifate_error_no_supp"]);
        }
        $certificate->delete();
    }

    /**
     * Récupération des paramètres du certificat
     *
     * @return object|null
     */
    public function getSettings()
    {
        return encoding_normalize::json_decode($this->settings);
    }

    /**
     * Offuscation des paramètres du certificat
     *
     * @param object $data
     * @return string
     */
    private static function offuscateSettings($data)
    {
        global $pmb_public_rsa_key, $pmb_private_rsa_key;

        if (empty($pmb_public_rsa_key) || empty($pmb_private_rsa_key)) {
            return encoding_normalize::json_encode($data->settings);
        }

        $crypto = new Crypto();
        $crypto->loadPMBRSAContext();
        foreach (self::SENSITIVE_FIELDS as $field) {
            if (!empty($data->settings->$field)) {
                if (strpos($data->settings->$field, Crypto::INDICATOR) === 0) {
                    // already encrypted
                    continue;
                }

                $data->settings->$field = $crypto->encryptToHexa($data->settings->$field);
            }
        }

        return encoding_normalize::json_encode($data->settings);
    }

    /**
     * Déoffuscation des paramètres du certificat
     *
     * @param object|null $data
     * @return object|null
     */
    private static function deOffuscateSettings($data)
    {
        global $pmb_public_rsa_key, $pmb_private_rsa_key;

        if ($data === null) {
            return null;
        }

        if (empty($pmb_public_rsa_key) || empty($pmb_private_rsa_key)) {
            return $data;
        }

        $crypto = new Crypto();
        $crypto->loadPMBRSAContext();
        foreach (self::SENSITIVE_FIELDS as $field) {
            if (!empty($data->$field) && strpos($data->$field, Crypto::INDICATOR) === 0) {
                $data->$field = $crypto->decryptFromHexa($data->$field);
            }
        }
        return $data;
    }
}
