-- 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.
local lu = require 'luaunit'
local otel_logs = require 'otel.logs'
local utils = require 'mc.utils'
local paser = require 'parser.log'
local dump_file = './otel_logs.txt'
TestLogs = {}

local SEVERITY_TRACE = 1
local SEVERITY_DEBUG = 5
local SEVERITY_INFO = 9
local SEVERITY_WARN = 13
local SEVERITY_ERROR = 17
local SEVERITY_FATAL = 21

function TestLogs:setupClass()
    otel_logs.init_logger_provider()
    self.logger = otel_logs.create_otel_logger('test_app')
end

function TestLogs:teardownClass()
    utils.remove_file('./otel_logs.txt')
end

function TestLogs:test_create_logger()
    self.logger:log(SEVERITY_TRACE, 'test_app trace log')
    self.logger:flush()
    
    local logs = paser:parse_log_file(dump_file)
    lu.assertEquals(logs[#logs].scope.name, 'test_app')
    lu.assertEquals(logs[#logs].body, 'test_app trace log')
    lu.assertEquals(logs[#logs].severity_num, '1')
    lu.assertEquals(logs[#logs].severity_text, 'TRACE')
    lu.assertEquals(logs[#logs].event_name, '')
    lu.assertEquals(logs[#logs].event_id, '0')
    lu.assertEquals(logs[#logs].trace_id, '00000000000000000000000000000000')
    lu.assertEquals(logs[#logs].trace_flags, '00')
    lu.assertEquals(logs[#logs].span_id, '0000000000000000')

    local logger = otel_logs.create_otel_logger('test_app2')
    logger:log(SEVERITY_TRACE, 'test_app2 trace log')
    logger:flush()
    
    local logs = paser:parse_log_file(dump_file)
    lu.assertEquals(logs[#logs].scope.name, 'test_app2')
    lu.assertEquals(logs[#logs].body, 'test_app2 trace log')
    lu.assertEquals(logs[#logs].severity_num, '1')
    lu.assertEquals(logs[#logs].severity_text, 'TRACE')
    lu.assertEquals(logs[#logs].event_name, '')
    lu.assertEquals(logs[#logs].event_id, '0')
    lu.assertEquals(logs[#logs].trace_id, '00000000000000000000000000000000')
    lu.assertEquals(logs[#logs].trace_flags, '00')
    lu.assertEquals(logs[#logs].span_id, '0000000000000000')

    self.logger:log(SEVERITY_TRACE, 'test_app trace log2')
    self.logger:flush()
    
    local logs = paser:parse_log_file(dump_file)
    lu.assertEquals(logs[#logs].scope.name, 'test_app')
    lu.assertEquals(logs[#logs].body, 'test_app trace log2')
    lu.assertEquals(logs[#logs].severity_num, '1')
    lu.assertEquals(logs[#logs].severity_text, 'TRACE')
    lu.assertEquals(logs[#logs].event_name, '')
    lu.assertEquals(logs[#logs].event_id, '0')
    lu.assertEquals(logs[#logs].trace_id, '00000000000000000000000000000000')
    lu.assertEquals(logs[#logs].trace_flags, '00')
    lu.assertEquals(logs[#logs].span_id, '0000000000000000')
end

function TestLogs:test_trace_logs()
    self.logger:log(SEVERITY_TRACE, 'test opentelemetry trace log', {key1 = 'key1_value'})
    self.logger:flush()
    
    local logs = paser:parse_log_file(dump_file)
    lu.assertEquals(logs[#logs].scope.name, 'test_app')
    lu.assertEquals(logs[#logs].body, 'test opentelemetry trace log')
    lu.assertEquals(logs[#logs].severity_num, '1')
    lu.assertEquals(logs[#logs].severity_text, 'TRACE')
    lu.assertEquals(logs[#logs].event_name, '')
    lu.assertEquals(logs[#logs].event_id, '0')
    lu.assertEquals(logs[#logs].trace_id, '00000000000000000000000000000000')
    lu.assertEquals(logs[#logs].trace_flags, '00')
    lu.assertEquals(logs[#logs].span_id, '0000000000000000')
    lu.assertEquals(logs[#logs].attributes.key1, 'key1_value')
end

function TestLogs:test_debug_logs()
    self.logger:log(SEVERITY_DEBUG, 'test opentelemetry debug log', {key2 = 'key2_value'})
    self.logger:flush()
    
    local logs = paser:parse_log_file(dump_file)
    lu.assertEquals(logs[#logs].scope.name, 'test_app')
    lu.assertEquals(logs[#logs].body, 'test opentelemetry debug log')
    lu.assertEquals(logs[#logs].severity_num, '5')
    lu.assertEquals(logs[#logs].severity_text, 'DEBUG')
    lu.assertEquals(logs[#logs].event_name, '')
    lu.assertEquals(logs[#logs].event_id, '0')
    lu.assertEquals(logs[#logs].trace_id, '00000000000000000000000000000000')
    lu.assertEquals(logs[#logs].trace_flags, '00')
    lu.assertEquals(logs[#logs].span_id, '0000000000000000')
    lu.assertEquals(logs[#logs].attributes.key2, 'key2_value')
end

function TestLogs:test_info_logs()
    self.logger:log(SEVERITY_INFO, 'test opentelemetry info log', {key3 = 'key3_value'})
    self.logger:flush()
    
    local logs = paser:parse_log_file(dump_file)
    lu.assertEquals(logs[#logs].scope.name, 'test_app')
    lu.assertEquals(logs[#logs].body, 'test opentelemetry info log')
    lu.assertEquals(logs[#logs].severity_num, '9')
    lu.assertEquals(logs[#logs].severity_text, 'INFO')
    lu.assertEquals(logs[#logs].event_name, '')
    lu.assertEquals(logs[#logs].event_id, '0')
    lu.assertEquals(logs[#logs].trace_id, '00000000000000000000000000000000')
    lu.assertEquals(logs[#logs].trace_flags, '00')
    lu.assertEquals(logs[#logs].span_id, '0000000000000000')
    lu.assertEquals(logs[#logs].attributes.key3, 'key3_value')
end

function TestLogs:test_warn_logs()
    self.logger:log(SEVERITY_WARN, 'test opentelemetry warn log', {key4 = 'key4_value'})
    self.logger:flush()
    
    local logs = paser:parse_log_file(dump_file)
    lu.assertEquals(logs[#logs].scope.name, 'test_app')
    lu.assertEquals(logs[#logs].body, 'test opentelemetry warn log')
    lu.assertEquals(logs[#logs].severity_num, '13')
    lu.assertEquals(logs[#logs].severity_text, 'WARN')
    lu.assertEquals(logs[#logs].event_name, '')
    lu.assertEquals(logs[#logs].event_id, '0')
    lu.assertEquals(logs[#logs].trace_id, '00000000000000000000000000000000')
    lu.assertEquals(logs[#logs].trace_flags, '00')
    lu.assertEquals(logs[#logs].span_id, '0000000000000000')
    lu.assertEquals(logs[#logs].attributes.key4, 'key4_value')
end

function TestLogs:test_error_logs()
    self.logger:log(SEVERITY_ERROR, 'test opentelemetry error log', {key5 = 'key5_value'})
    self.logger:flush()
    
    local logs = paser:parse_log_file(dump_file)
    lu.assertEquals(logs[#logs].scope.name, 'test_app')
    lu.assertEquals(logs[#logs].body, 'test opentelemetry error log')
    lu.assertEquals(logs[#logs].severity_num, '17')
    lu.assertEquals(logs[#logs].severity_text, 'ERROR')
    lu.assertEquals(logs[#logs].event_name, '')
    lu.assertEquals(logs[#logs].event_id, '0')
    lu.assertEquals(logs[#logs].trace_id, '00000000000000000000000000000000')
    lu.assertEquals(logs[#logs].trace_flags, '00')
    lu.assertEquals(logs[#logs].span_id, '0000000000000000')
    lu.assertEquals(logs[#logs].attributes.key5, 'key5_value')
end

function TestLogs:test_fatal_logs()
    self.logger:log(SEVERITY_FATAL, 'test opentelemetry fatal log', {key6 = 'key6_value'})
    self.logger:flush()
    
    local logs = paser:parse_log_file(dump_file)
    lu.assertEquals(logs[#logs].scope.name, 'test_app')
    lu.assertEquals(logs[#logs].body, 'test opentelemetry fatal log')
    lu.assertEquals(logs[#logs].severity_num, '21')
    lu.assertEquals(logs[#logs].severity_text, 'FATAL')
    lu.assertEquals(logs[#logs].event_name, '')
    lu.assertEquals(logs[#logs].event_id, '0')
    lu.assertEquals(logs[#logs].trace_id, '00000000000000000000000000000000')
    lu.assertEquals(logs[#logs].trace_flags, '00')
    lu.assertEquals(logs[#logs].span_id, '0000000000000000')
    lu.assertEquals(logs[#logs].attributes.key6, 'key6_value')
end

function TestLogs:test_span_logs()
    self.logger:log(SEVERITY_FATAL, 'test span log', {key7 = 'key7_value', trace_id = "490dfe733e378c7a86817d4683280225", span_id = "6f9d4c13aa638380", trace_flags = 1})
    self.logger:flush()
    
    local logs = paser:parse_log_file(dump_file)
    lu.assertEquals(logs[#logs].trace_id, '490dfe733e378c7a86817d4683280225')
    lu.assertEquals(logs[#logs].trace_flags, '01')
    lu.assertEquals(logs[#logs].span_id, '6f9d4c13aa638380')
    lu.assertEquals(logs[#logs].attributes.key7, 'key7_value')

    self.logger:log(SEVERITY_FATAL, 'test span log', {key7 = 'key7_value', trace_id = "622787f3a97acce007ac0310b9b0ee75", span_id = "c19cce0efa79c56d", trace_flags = 0})
    self.logger:flush()
    
    local logs = paser:parse_log_file(dump_file)
    lu.assertEquals(logs[#logs].trace_id, '622787f3a97acce007ac0310b9b0ee75')
    lu.assertEquals(logs[#logs].trace_flags, '00')
    lu.assertEquals(logs[#logs].span_id, 'c19cce0efa79c56d')
    lu.assertEquals(logs[#logs].attributes.key7, 'key7_value')
end