/* Copyright (c) 2025 Huawei Technologies Co., Ltd.
 * openUBMC is licensed under 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.
 */
#ifndef PD_LOG_ADAPTER
#define PD_LOG_ADAPTER

#include <dlfcn.h>
#include "l_pd.h"

struct new_pd_log {
    guint8 log_source; // 0 - OOB, 1 - BMA, 其它值无效
    guint8 log_rotate_num;
    guint8 pd_power_state;
    guint8 pd_interface_type;
    guint8 pd_media_type;
    guint8 pd_slot_number;
    guint8 pd_remnant_media_wearout;
    guint16 pd_enclosure_id;
    gchar pd_device_name[PROP_VAL_LENGTH];
    gchar pd_interface_type_str[PROP_VAL_LENGTH];
    gchar pd_manufacturer[SML_PD_MANUFACTURER_LENGTH];
    gchar pd_serial_number[SML_PD_SN_LENGTH];
    gchar pd_model[SML_PD_MODEL_LENGTH];
    guint8 pd_rebuild_progress;
    guint8 pd_health;
    guint32 pd_perfail_error_count;
    guint32 pd_media_error_count;
    guint32 pd_other_error_count;

    union {
        struct {
            SML_PD_LOG_DATA_S smart_attribute;
            SML_PD_LOG_DATA_S smart_attribute_threshold;
            SML_PD_LOG_DATA_S error;
            SML_PD_LOG_DATA_S extent_error;
            SML_PD_LOG_DATA_S extended_selftest;
            SML_PD_LOG_DATA_S phy_event;
            SML_PD_LOG_DATA_S seagate_glist;
            SML_PD_LOG_DATA_S seagate_plist;
            SML_PD_LOG_DATA_S seagate_critical_event;
            SML_PD_LOG_DATA_S seagate_farm;
            SML_PD_LOG_DATA_S seagate_factory_farm;
        } SATADevice;

        struct {
            SML_PD_LOG_DATA_S selftest;
            SML_PD_LOG_DATA_S read_error_cnt;
            SML_PD_LOG_DATA_S write_error_cnt;
            SML_PD_LOG_DATA_S verify_error_cnt;
            SML_PD_LOG_DATA_S nonmedium_error_cnt;
            SML_PD_LOG_DATA_S phy_error_cnt;
            SML_PD_LOG_DATA_S glist;
            SML_PD_LOG_DATA_S temperature;
            SML_PD_LOG_DATA_S ie;
            SML_PD_LOG_DATA_S bms;
            SML_PD_LOG_DATA_S general_statistics;
            SML_PD_LOG_DATA_S read_latency_statistics;
            SML_PD_LOG_DATA_S write_latency_statistics;
            SML_PD_LOG_DATA_S huawei_specific32h;
            SML_PD_LOG_DATA_S huawei_specific34h;
            SML_PD_LOG_DATA_S huawei_specific35h;
            SML_PD_LOG_DATA_S huawei_io_info;
            SML_PD_LOG_DATA_S kioxia_ssd_specific;
            SML_PD_LOG_DATA_S kioxia_eopt;
            SML_PD_LOG_DATA_S kioxia_smart_data;
        } SASDevice;
    };
};

using PD_DIAGNOSE_INFO = struct new_pd_log;

namespace sml {
using AdapterIODeteriorationHandleBasicData = void (*)(PD_LOG_S *pd_log, Json *pd_io_info_jso);
using AdapterIODeteriorationHandleData = void (*)(PD_LOG_S *pd_log, Json *pd_io_info_jso);
using AdapterPdLogCollectRawDataFromOob = void (*)(guint8 ctrl_index, guint16 pd_device_id,
    SML_PD_LOG_DATA_S *pd_log_raw_data, guint32 pd_log_collect_timeout);
using AdapterPdLogClearData = void (*)(PD_LOG_S *pd_log);
using AdapterPdLogCollectSasFromOob = gint32 (*)(guint8 ctrl_index, guint16 pd_device_id, PD_LOG_S *pd_log);
using AdapterPdLogHandleSas = void (*)(PD_LOG_S *pd_log, Json *pd_log_jso);
using AdapterPdLogHandleSataSmart = void (*)(FILE *file, PD_LOG_S *pd_log, void *out_put);
using AdapterPdLogHandleSataExtError = void (*)(FILE *file, PD_LOG_S *pd_log, void *out_put, Json *pd_log_jso);
using AdapterPdLogHandleSataExtSelfTest = void (*)(FILE *file, PD_LOG_S *pd_log, void *out_put, Json *pd_log_jso);
using AdapterPdLogHandleSata = void (*)(PD_LOG_S *pd_log, Json *pd_log_jso);
using AdapterPdLogCollectSataFromOob = gint32 (*)(guint8 ctrl_index, guint16 pd_device_id, PD_LOG_S *pd_log);
using AdapterCalcAndSaveWriteAmpValueBySmartInfo = void (*)(char *device_name, guint32 est_lfsp_value,
    SML_PD_SSD_WRITE_AMP_FACTOR_S *write_amp_info, WRITE_AMP_LAST_INFO_S *write_amp_last_info,
    Json *disk_write_amp_jso);
using AdapterSavePdLogParseFunTable = void (*)(PD_LOG_PARSE **pd_log_parse);
using AdapterPdLogCollectSasIoLatencyFromOob = gint32 (*)(guint8 ctrl_index, guint16 pd_device_id,
    PD_DIAGNOSE_INFO *pd_log);


using PD_LOG_ADAPTER_S = struct _tag_pd_log_adapter {
    AdapterIODeteriorationHandleBasicData io_deterioration_handle_basic_data;
    AdapterIODeteriorationHandleData io_deterioration_handle_data;
    AdapterPdLogCollectRawDataFromOob pd_log_collect_raw_data_from_oob;
    AdapterPdLogClearData pd_log_clear_data;
    AdapterPdLogCollectSasFromOob pd_log_collect_sas_from_oob;
    AdapterPdLogHandleSas pd_log_handle_sas;
    AdapterPdLogHandleSataSmart pd_log_handle_sata_smart;
    AdapterPdLogHandleSataExtError pd_log_handle_sata_ext_error;
    AdapterPdLogHandleSataExtSelfTest pd_log_handle_sata_ext_self_test;
    AdapterPdLogHandleSata pd_log_handle_sata;
    AdapterPdLogCollectSataFromOob pd_log_collect_sata_from_oob;
    AdapterCalcAndSaveWriteAmpValueBySmartInfo calc_and_save_write_amp_value_by_smart_info;
    AdapterSavePdLogParseFunTable save_pd_log_parse_fun_table;
    AdapterPdLogCollectSasIoLatencyFromOob pd_log_collect_write_io_latency_from_oob;
    AdapterPdLogCollectSasIoLatencyFromOob pd_log_collect_read_io_latency_from_oob;
};

class pd_log_adapter {
public:
    static void adapter_io_deterioration_handle_basic_data(PD_LOG_S *pd_log, Json *pd_io_info_jso);
    static void adapter_io_deterioration_handle_data(PD_LOG_S *pd_log, Json *pd_io_info_jso);
    static void adapter_pd_log_collect_raw_data_from_oob(guint8 ctrl_index, guint16 pd_device_id,
        SML_PD_LOG_DATA_S *pd_log_raw_data, guint32 pd_log_collect_timeout);
    static void adapter_pd_log_clear_data(PD_LOG_S *pd_log);
    static gint32 adapter_pd_log_collect_sas_from_oob(guint8 ctrl_index, guint16 pd_device_id, PD_LOG_S *pd_log);
    static void adapter_pd_log_handle_sas(PD_LOG_S *pd_log, Json *pd_log_jso);
    static void adapter_pd_log_handle_sata_smart(FILE *file, PD_LOG_S *pd_log, void *out_put);
    static void adapter_pd_log_handle_sata_ext_error(FILE *file, PD_LOG_S *pd_log, void *out_put, Json *pd_log_jso);
    static void adapter_pd_log_handle_sata_ext_self_test(FILE *file, PD_LOG_S *pd_log,
        void *out_put, Json *pd_log_jso);
    static void adapter_pd_log_handle_sata(PD_LOG_S *pd_log, Json *pd_log_jso);
    static gint32 adapter_pd_log_collect_sata_from_oob(guint8 ctrl_index, guint16 pd_device_id, PD_LOG_S *pd_log);
    static gint32 adapter_pd_log_collect_write_io_latency_from_oob(guint8 ctrl_index, guint16 pd_device_id,
        PD_DIAGNOSE_INFO *pd_log);
    static gint32 adapter_pd_log_collect_read_io_latency_from_oob(guint8 ctrl_index, guint16 pd_device_id,
        PD_DIAGNOSE_INFO *pd_log);

    static void adapter_calc_and_save_write_amp_value_by_smart_info(char *device_name, guint32 est_lfsp_value,
        SML_PD_SSD_WRITE_AMP_FACTOR_S *write_amp_info, WRITE_AMP_LAST_INFO_S *write_amp_last_info,
        Json *disk_write_amp_jso);
    static void adapter_save_pd_log_parse_fun_table(PD_LOG_PARSE **pd_log_parse);
};
} // namespace pd_log_parse

#endif