/*
 * Copyright (c) 2023 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.
 */

#include "chip.h"
#include <mc/exception.h>
#include <mc/log.h>

using namespace dev;

bool complex_object::init(mc::mutable_dict& csr_object, const mc::dict& connector)
{
    try {
        // 验证参数
        if (csr_object.empty()) {
            MC_THROW(mc::invalid_op_exception, "csr_object is empty");
        }

        auto& manager      = dev::device_manager::get_instance();
        auto  chip_variant = manager.find_object(csr_object["object_name"].as<std::string>(), dev::object_type::chip);
        if (std::holds_alternative<std::shared_ptr<chip_base>>(chip_variant)) {
            auto chip_ptr = std::get<std::shared_ptr<chip_base>>(chip_variant);
            if (chip_ptr) {
                m_interface_chip.m_chip    = static_cast<dev::chip_base*>(chip_ptr.get());
                m_interface_blockio.m_chip = static_cast<dev::chip_base*>(chip_ptr.get());
                m_interface_chip.from_variant(csr_object);
            } else {
                MC_THROW(mc::invalid_op_exception, "chip not found, name: ${name}",
                         ("name", csr_object["object_name"].as<std::string>()));
            }
        } else {
            MC_THROW(mc::invalid_op_exception, "chip not found, name: ${name}",
                     ("name", csr_object["object_name"].as<std::string>()));
        }
    } catch (const std::exception& e) {
        elog("Complex chip init failed, exception: ${exception}", ("exception", e.what()));
        return false;
    }

    return true;
}

std::string complex_object::dump()
{
    try {
        if (m_interface_chip.m_chip == nullptr) {
            elog("complex chip device not initialized");
            return "";
        }

        auto result = m_interface_chip.m_chip->dump();
        ilog("complex chip dump successfully");
        return result;
    } catch (const std::exception& e) {
        elog("complex chip device dump exception: ${error}", ("error", e.what()));
        return "";
    }
}

MC_REFLECT(dev::complex_object, ((m_interface_chip, "bmc.dev.Chip"))((m_interface_blockio, "bmc.kepler.Chip.BlockIO")))