-- Copyright (c) 2024 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.
local mdb = require 'mc.mdb'
local utils = require 'mc.utils'
local logging = require 'mc.logging'
local class = require 'mc.class_mgnt'
local err = require 'validate.errors'
local privilege = require 'mc.privilege'

local get_table_node = utils.get_table_node

local heartbeat_mdb_prop_configs = {
    ['bmc.kepler.Managers.HeartBeat'] = {
        ['Name'] = {
            ['baseType'] = 'String',
            ['readOnly'] = true,
            ['options'] = {['emitsChangedSignal'] = false},
            ['description'] = '监控心跳的实体名称',
            ['usage'] = {'CSR'},
            ['validator'] = require'rack_mgmt.json_types.HeartBeat'.Name
        },
        ['Status'] = {
            ['baseType'] = 'String',
            ['readOnly'] = true,
            ['options'] = {['emitsChangedSignal'] = false},
            ['description'] = '当前心跳状态',
            ['usage'] = {'CSR'},
            ['validator'] = require'rack_mgmt.json_types.HeartBeat'.Status
        }
    },
    ['bmc.kepler.Object.Properties'] = {
        ['ClassName'] = {
            ['baseType'] = 'String',
            ['readOnly'] = true,
            ['validator'] = require'rack_mgmt.json_types.Properties'.ClassName
        },
        ['ObjectName'] = {
            ['baseType'] = 'String',
            ['readOnly'] = true,
            ['validator'] = require'rack_mgmt.json_types.Properties'.ObjectName
        },
        ['ObjectIdentifier'] = {
            ['baseType'] = 'Struct',
            ['$ref'] = '#/defs/StructIdentifier',
            ['readOnly'] = true,
            ['validator'] = require'rack_mgmt.json_types.Properties'.ObjectIdentifier
        }
    }
}

local HeartBeat = {
    ['table_name'] = 't_heart_beat',
    ['alias_map'] = {},
    ['prop_configs'] = {},
    ['default_props'] = {},
    ['mdb_prop_configs'] = heartbeat_mdb_prop_configs,
    ['mdb_method_configs'] = {
        ['bmc.kepler.Managers.HeartBeat'] = {['Beat'] = {['privilege'] = {'ReadOnly'}, ['req'] = {}, ['rsp'] = {}}}
    },
    ['mdb_signal_configs'] = {},
    ['mdb_classes'] = mdb.get_class_obj('/bmc/kepler/Managers/:ManagerId/HeartBeat/:Id'),
    ['new_mdb_objects'] = function(path)
        local objs = {}
        local obj_cls, params = mdb.match_interface(path, 'bmc.kepler.Managers.HeartBeat')
        if not obj_cls then
            logging:warn('Not match interface, path:%s, interface:%s', path, 'bmc.kepler.Managers.HeartBeat')
        else
            local obj = obj_cls.new(table.unpack(params))
            obj['Name'] = require'rack_mgmt.json_types.HeartBeat'.Name.default[1]
            obj['Status'] = require'rack_mgmt.json_types.HeartBeat'.Status.default[1]
            obj:access_control({path = privilege.ReadOnly, props = {}, methods = {['Beat'] = privilege.ReadOnly}},
                {['Name'] = true, ['Status'] = true}, require 'rack_mgmt.json_types.HeartBeat')
            objs['bmc.kepler.Managers.HeartBeat'] = obj
        end
        obj_cls, params = mdb.match_interface(path, 'bmc.kepler.Object.Properties')
        if not obj_cls then
            logging:warn('Not match interface, path:%s, interface:%s', path, 'bmc.kepler.Object.Properties')
        else
            local obj = obj_cls.new(table.unpack(params))
            obj['ClassName'] = require'rack_mgmt.json_types.Properties'.ClassName.default[1]
            obj['ObjectName'] = require'rack_mgmt.json_types.Properties'.ObjectName.default[1]
            obj['ObjectIdentifier'] = require'rack_mgmt.json_types.Properties'.ObjectIdentifier.default[1]
            obj:access_control({path = privilege.ReadOnly, props = {}, methods = {}},
                {['ClassName'] = true, ['ObjectName'] = true, ['ObjectIdentifier'] = true},
                require 'rack_mgmt.json_types.Properties')
            objs['bmc.kepler.Object.Properties'] = obj
        end
        return objs
    end
}

local M = {}

function M.init(bus)
    class('HeartBeat', HeartBeat):set_bus(bus)
end

-- The callback needs to be registered during app initialization
function M.ImplHeartBeatHeartBeatBeat(cb)
    class('HeartBeat')['bmc.kepler.Managers.HeartBeat'].Beat = function(obj, ctx, ...)
        local heartbeat_types = require 'rack_mgmt.json_types.HeartBeat'
        local req = heartbeat_types.BeatReq.new(...):validate(nil, nil, true)
        local rsp = heartbeat_types.BeatRsp.new(cb(obj, ctx, req:unpack())):validate()
        return rsp:unpack(true)
    end
end

return M
