/*
 * Copyright (c) Huawei Technologies Co., Ltd. 2025. All rights reserved.
 * Global Trust Authority is licensed under the Mulan PSL v2.
 * You can use this software according to the terms and conditions of the Mulan PSL v2.
 * You may obtain a copy of Mulan PSL v2 at:
 *     http://license.coscl.org.cn/MulanPSL2
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
 * PURPOSE.
 * See the Mulan PSL v2 for more details.
 */

// Plugin trait definitions

use async_trait::async_trait;
use serde_json::Value;
use std::result::Result;
use thiserror::Error;

/// Management trait - shared by all plugins
#[async_trait]
pub trait PluginBase: Send + Sync {
    fn plugin_type(&self) -> &str;
}

#[async_trait]
pub trait ServicePlugin: PluginBase {
    /// Get sample output for the plugin
    ///
    /// Returns a sample JSON output that demonstrates the structure of the plugin's
    /// verification results. This is useful for documentation and testing.
    ///
    /// # Returns
    ///
    /// Returns a JSON `Value` representing a sample output from this plugin
    fn get_sample_output(&self) -> Value;

    /// Verify evidence submitted by an agent
    ///
    /// Verifies the evidence provided by an agent for attestation. The evidence
    /// is validated according to the plugin's specific verification logic.
    ///
    /// # Arguments
    ///
    /// * `user_id` - The unique identifier of the user requesting attestation
    /// * `node_id` - Optional node identifier for multi-node environments
    /// * `evidence` - The evidence data to verify, provided as JSON
    /// * `nonce` - Optional nonce value for replay protection
    ///
    /// # Returns
    ///
    /// Returns a JSON `Value` containing the verification result on success,
    /// or a `PluginError` if verification fails
    ///
    /// # Errors
    ///
    /// Returns `PluginError` if:
    /// - Evidence format is invalid
    /// - Verification logic fails
    /// - Required fields are missing
    async fn verify_evidence(
        &self,
        user_id: &str,
        node_id: Option<&str>,
        evidence: &Value,
        nonce: Option<&[u8]>,
    ) -> Result<Value, PluginError>;

    /// Generate primary data from plugin results
    ///
    /// # Arguments
    /// * `ueid` - Unique Entity ID
    /// * `secure_boot` - Secure boot status (as boolean)
    /// * `dbgstat` - Debug status
    ///
    /// # Returns
    /// * `Value` - Primary data in JSON format
    fn generate_primary_data(&self, ueid: Option<&str>, secure_boot: Option<bool>, dbgstat: Option<&str>) -> Value {
        serde_json::json!({
            "ueid": ueid,
            "secure_boot": secure_boot,
            "dbgstat": dbgstat
        })
    }
}

pub trait AgentPlugin: PluginBase {
    /// Collects evidence based on the provided parameters.
    ///
    /// # Errors
    ///
    /// Returns `PluginError` if:
    /// - Failed to collect evidence
    /// - Evidence parameters are invalid
    /// - Any other error occurs during evidence collection
    fn collect_evidence(&self, evidence_params: CollectEvidenceParams) -> Result<Value, PluginError>;
}

/// Trait for getting singleton instances of plugin managers
pub trait PluginManagerInstance {
    fn get_instance() -> &'static Self;
}

#[derive(Error, Debug)]
pub enum PluginError {
    #[error("Input error: {0}")]
    InputError(String),

    #[error("Internal error: {0}")]
    InternalError(String),
}

pub struct CollectEvidenceParams {
    pub node_id: Option<String>,
    pub nonce: Option<Vec<u8>>,
    pub log_types: Option<Vec<String>>,
    pub attester_ids: Option<Vec<String>>,
}