local open_db = require 'observability.db'
local utils = require 'mc.utils'
local datas = require 'observability.datas'
local db_path = './test_observability_mock.test.db'
local m_config = require 'public.config'
local m_control = require 'public.control'
local defs = require 'public.defs'
local unit_data_dir = utils.realpath('.')
local cert_dir = unit_data_dir .. '/cert_key'
local cert_file = cert_dir .. '/SSL.key'
local vos = require 'utils.vos'
local file_sec = require 'utils.file'
local policy_config = require 'mdb_server.policy_config'
local client = require 'observability.client'

TestMock = {}

function TestMock:setupClass()
    self.db = open_db(db_path, datas)
    self.config = m_config.new(self.db)
    self.control = m_control.new(self.db)

    os.execute('mkdir -p ' .. cert_dir)
    os.execute('touch ' .. defs.TLS_CA_FILE_PATH)
    os.execute('echo test > ' .. defs.TLS_CA_FILE_PATH)
    os.execute('touch ' .. cert_file)
    os.execute('echo test > ' .. cert_file)
    os.execute('mkdir -p ' .. defs.SSL_KEY_PATH)
    os.execute('touch ' .. defs.SSL_KEY_FILE_PATH)
end

function TestMock:teardownClass()
    os.execute('rm -f ' .. db_path)
    utils.remove_file(defs.TLS_CA_FILE_PATH)
    utils.remove_file(cert_file)
    utils.remove_file(defs.SSL_KEY_FILE_PATH)
end

function TestMock:test_start_fluent_bit_mock()
    self.db:update(self.db.ObservabilityService):value({TLSMode = "mTLS"}):exec()
    self.control:fluent_bit_service_start()
    vos.system_s = function(...)
        return 0
    end
    file_sec.open_s = function(...)
        return nil
    end
    self.control:start_fluent_bit_service("fluent-bit")

    self.control.config.generate = function(...)
        return true
    end
    self.control:fluent_bit_service_start()
end

function TestMock:test_write_fifo_mock()
    self.db:update(self.db.ObservabilityService):value({TLSMode = "mTLS"}):exec()
    file_sec.check_realpath_before_open_s = function(...)
        return -1
    end
    self.config.key_text = ' '
    self.config:get_persistence_config(0)

    file_sec.open_s = function(...)
        return nil
    end
    self.config:get_persistence_config(0)

    self.db.select = function(...)
        return {first = function(...)
            return nil
        end}
    end
    local ok = pcall(function ()
        self.config:write_data_to_fifo()
    end)
    assert(ok)
end

function TestMock:test_generate_identity_config()
    self.db:update(self.db.ObservabilityService):value({TLSMode = "TLS"}):exec()
    local ok = pcall(function ()
        self.config:get_persistence_config(0)
    end)
    assert(ok)

    self.db:update(self.db.ObservabilityService):value({ServerIdentity = "ProductAssetTag"}):exec()
    ok = pcall(function ()
        self.config:get_persistence_config(0)
    end)
    assert(ok)

    self.db:update(self.db.ObservabilityService):value({ServerIdentity = "HostName"}):exec()
    ok = pcall(function ()
        self.config:get_persistence_config(0)
    end)
    assert(ok)
end

function TestMock:test_set_logs_config()
    client.GetDashboardObservabilityLogsObject = function ()
        return nil
    end
    local config = {Enabled = true}
    local ok = pcall(function ()
        policy_config:set_logs_config(config)
    end)
    assert(not ok)
end

function TestMock:test_set_metrics_config()
    client.GetDashboardObservabilityMetricsObject = function ()
        return nil
    end
    local config = {ExportIntervalSeconds = 10}
    local ok = pcall(function ()
        policy_config:set_metrics_config(config)
    end)
    assert(not ok)
end

function TestMock:test_set_traces_config()
    client.GetDashboardObservabilityTracesObject = function ()
        return nil
    end
    local config = {SamplingRate = 0.5}
    local ok = pcall(function ()
        policy_config:set_traces_config(config)
    end)
    assert(not ok)
end

function TestMock:test_service_control()
    local ok = pcall(function ()
        self.control:is_service_alive('')
    end)
    assert(ok)

    ok = pcall(function ()
        self.control:start_fluent_bit_service('')
    end)
    assert(ok)

    ok = pcall(function ()
        self.control:stop_fluent_bit_service('')
    end)
    assert(ok)

    vos.system_s = function(...)
        return -1
    end

    ok = pcall(function ()
        self.control:start_fluent_bit_service('')
    end)
    assert(ok)

    ok = pcall(function ()
        self.control:start_fluent_bit_service('fluent-bit')
    end)
    assert(ok)

    ok = pcall(function ()
        self.control:stop_fluent_bit_service('fluent-bit')
    end)
    assert(ok)

    ok = pcall(function ()
        self.control:fluent_bit_service_restart()
    end)
    assert(ok)
end