// SPDX-FileCopyrightText: 2018 - 2022 UnionTech Software Technology Co., Ltd.
//
// SPDX-License-Identifier: GPL-3.0-or-later

package audio

import (
	"sync"
	"time"

	dbus "github.com/godbus/dbus"
	"github.com/linuxdeepin/go-lib/dbusutil"
	"github.com/linuxdeepin/go-lib/pulse"
)

// Meter 音频计量器结构体
// 用于监控音频输入设备的音量水平
type Meter struct {
	audio   *Audio // 音频管理实例
	service *dbusutil.Service // DBus服务
	PropsMu sync.RWMutex // 属性读写锁
	Volume  float64 // 当前音量值
	id      string // 计量器ID
	alive   bool // 是否活跃状态
	core    *pulse.SourceMeter // 脉冲音频源计量器核心对象
}

// newMeter 创建新的音频计量器实例
// id: 计量器ID
// core: 脉冲音频源计量器对象
// audio: 音频管理实例
// TODO: use pulse.Meter instead of remove pulse.SourceMeter
func newMeter(id string, core *pulse.SourceMeter, audio *Audio) *Meter {
	m := &Meter{
		id:      id,
		core:    core,
		audio:   audio,
		service: audio.service,
	}
	err := m.Tick()
	if err != nil {
		logger.Warning(err)
	}
	go m.tryQuit()
	return m
}

// quit 退出计量器
// 清理资源并停止导出
func (m *Meter) quit() {
	m.audio.mu.Lock()
	delete(m.audio.meters, m.id)
	m.audio.mu.Unlock()

	err := m.service.StopExport(m)
	if err != nil {
		logger.Warning(err)
	}
	m.core.Destroy()
}

// tryQuit 尝试退出计量器
// 每10秒检查一次活跃状态，如果非活跃则退出
func (m *Meter) tryQuit() {
	defer m.quit()

	for {
		time.Sleep(time.Second * 10)
		m.PropsMu.Lock()
		if !m.alive {
			m.PropsMu.Unlock()
			return
		}
		m.alive = false
		m.PropsMu.Unlock()
	}
}

// Tick 心跳检测
// 标记计量器为活跃状态，用于保持计量器存活
func (m *Meter) Tick() *dbus.Error {
	logger.Infof("dbus call Tick")

	m.PropsMu.Lock()
	m.alive = true
	m.PropsMu.Unlock()
	return nil
}

// getPath 获取DBus对象路径
// 返回计量器的DBus对象路径
func (m *Meter) getPath() dbus.ObjectPath {
	return dbus.ObjectPath(dbusPath + "/Meter" + m.id)
}

// GetInterfaceName 获取DBus接口名称
// 返回计量器的DBus接口名称
func (*Meter) GetInterfaceName() string {
	return dbusInterface + ".Meter"
}
