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

package audio

import (
	"encoding/json"

	dbus "github.com/godbus/dbus"
	soundthemeplayer "github.com/linuxdeepin/go-dbus-factory/com.deepin.api.soundthemeplayer"
	gio "github.com/linuxdeepin/go-gir/gio-2.0"
)

const (
	gsKeyAudioVolumeChange       = "audio-volume-change"       // 音频音量变化音效
	gsKeyCameraShutter           = "camera-shutter"           // 相机快门音效
	gsKeyCompleteCopy            = "complete-copy"            // 复制完成音效
	gsKeyCompletePrint           = "complete-print"           // 打印完成音效
	gsKeyDesktopLogin            = "desktop-login"            // 桌面登录音效
	gsKeyDesktopLogout           = "desktop-logout"           // 桌面登出音效
	gsKeyDeviceAdded             = "device-added"             // 设备添加音效
	gsKeyDeviceRemoved           = "device-removed"           // 设备移除音效
	gsKeyDialogErrorCritical     = "dialog-error-critical"     // 严重错误对话框音效
	gsKeyDialogError             = "dialog-error"             // 错误对话框音效
	gsKeyDialogErrorSerious      = "dialog-error-serious"      // 严重错误对话框音效
	gsKeyMessage                 = "message"                 // 消息音效
	gsKeyPowerPlug               = "power-plug"               // 电源插入音效
	gsKeyPowerUnplug             = "power-unplug"             // 电源拔出音效
	gsKeyPowerUnplugBatteryLow   = "power-unplug-battery-low"   // 电源拔出电池低电量音效
	gsKeyScreenCaptureComplete   = "screen-capture-complete"   // 屏幕截图完成音效
	gsKeyScreenCapture           = "screen-capture"           // 屏幕截图音效
	gsKeySuspendResume           = "suspend-resume"           // 挂起恢复音效
	gsKeySystemShutdown          = "system-shutdown"          // 系统关机音效
	gsKeyTrashEmpty              = "trash-empty"              // 清空回收站音效
	gsKeyXDeepinAppSentToDesktop = "x-deepin-app-sent-to-desktop" // 应用发送到桌面音效
)

// syncSoundEffect 同步音效配置结构体
// 包含各种系统音效的启用状态
type syncSoundEffect struct {
	Enabled                 bool `json:"enabled"`                 // 是否启用音效
	AudioVolumeChange       bool `json:"audio_volume_change"`       // 音频音量变化音效
	CameraShutter           bool `json:"camera_shutter"`           // 相机快门音效
	CompleteCopy            bool `json:"complete_copy"`            // 复制完成音效
	CompletePrint           bool `json:"complete_print"`           // 打印完成音效
	DesktopLogin            bool `json:"desktop_login"`            // 桌面登录音效
	DesktopLogout           bool `json:"desktop_logout"`           // 桌面登出音效
	DeviceAdded             bool `json:"device_added"`             // 设备添加音效
	DeviceRemoved           bool `json:"device_removed"`           // 设备移除音效
	DialogErrorCritical     bool `json:"dialog_error_critical"`     // 严重错误对话框音效
	DialogError             bool `json:"dialog_error"`             // 错误对话框音效
	DialogErrorSerious      bool `json:"dialog_error_serious"`      // 严重错误对话框音效
	Message                 bool `json:"message"`                 // 消息音效
	PowerPlug               bool `json:"power_plug"`               // 电源插入音效
	PowerUnplug             bool `json:"power_unplug"`             // 电源拔出音效
	PowerUnplugBatteryLow   bool `json:"power_unplug_battery_low"`   // 电源拔出电池低电量音效
	ScreenCaptureComplete   bool `json:"screen_capture_complete"`   // 屏幕截图完成音效
	ScreenCapture           bool `json:"screen_capture"`           // 屏幕截图音效
	SuspendResume           bool `json:"suspend_resume"`           // 挂起恢复音效
	SystemShutdown          bool `json:"system_shutdown"`          // 系统关机音效
	TrashEmpty              bool `json:"trash_empty"`              // 清空回收站音效
	XDeepinAppSentToDesktop bool `json:"x_deepin_app_sent_to_desktop"` // 应用发送到桌面音效
}

// syncData 同步数据结构体
// 包含版本信息和音效配置
type syncData struct {
	Version     string           `json:"version"`     // 同步版本
	SoundEffect *syncSoundEffect `json:"soundeffect"` // 音效配置
}

// syncConfig 同步配置结构体
// 用于深度同步功能的配置管理
type syncConfig struct {
	a *Audio // 音频管理实例
}

const (
	syncVersion = "1.0" // 同步版本号
)

// Get 获取同步配置数据
// 从GSettings读取音效配置并返回同步数据
// 返回同步数据对象和错误信息
func (sc *syncConfig) Get() (interface{}, error) {
	s := gio.NewSettings(gsSchemaSoundEffect)
	defer s.Unref()
	return &syncData{
		Version: syncVersion,
		SoundEffect: &syncSoundEffect{
			Enabled:                 s.GetBoolean(gsKeyEnabled),
			AudioVolumeChange:       s.GetBoolean(gsKeyAudioVolumeChange),
			CameraShutter:           s.GetBoolean(gsKeyCameraShutter),
			CompleteCopy:            s.GetBoolean(gsKeyCompleteCopy),
			CompletePrint:           s.GetBoolean(gsKeyCompletePrint),
			DesktopLogin:            s.GetBoolean(gsKeyDesktopLogin),
			DesktopLogout:           s.GetBoolean(gsKeyDesktopLogout),
			DeviceAdded:             s.GetBoolean(gsKeyDeviceAdded),
			DeviceRemoved:           s.GetBoolean(gsKeyDeviceRemoved),
			DialogErrorCritical:     s.GetBoolean(gsKeyDialogErrorCritical),
			DialogError:             s.GetBoolean(gsKeyDialogError),
			DialogErrorSerious:      s.GetBoolean(gsKeyDialogErrorSerious),
			Message:                 s.GetBoolean(gsKeyMessage),
			PowerPlug:               s.GetBoolean(gsKeyPowerPlug),
			PowerUnplug:             s.GetBoolean(gsKeyPowerUnplug),
			PowerUnplugBatteryLow:   s.GetBoolean(gsKeyPowerUnplugBatteryLow),
			ScreenCaptureComplete:   s.GetBoolean(gsKeyScreenCaptureComplete),
			ScreenCapture:           s.GetBoolean(gsKeyScreenCapture),
			SuspendResume:           s.GetBoolean(gsKeySuspendResume),
			SystemShutdown:          s.GetBoolean(gsKeySystemShutdown),
			TrashEmpty:              s.GetBoolean(gsKeyTrashEmpty),
			XDeepinAppSentToDesktop: s.GetBoolean(gsKeyXDeepinAppSentToDesktop),
		},
	}, nil
}

// Set 设置同步配置数据
// data: JSON格式的同步数据
// 将同步数据写入GSettings
func (sc *syncConfig) Set(data []byte) error {
	var info syncData
	err := json.Unmarshal(data, &info)
	if err != nil {
		return err
	}
	soundEffect := info.SoundEffect
	if soundEffect != nil {
		s := gio.NewSettings(gsSchemaSoundEffect)
		s.SetBoolean(gsKeyEnabled, soundEffect.Enabled)
		s.SetBoolean(gsKeyAudioVolumeChange, soundEffect.AudioVolumeChange)
		s.SetBoolean(gsKeyCameraShutter, soundEffect.CameraShutter)
		s.SetBoolean(gsKeyCompleteCopy, soundEffect.CompleteCopy)
		s.SetBoolean(gsKeyCompletePrint, soundEffect.CompletePrint)
		s.SetBoolean(gsKeyDesktopLogin, soundEffect.DesktopLogin)
		err = sc.syncConfigToSoundThemePlayer(soundEffect.DesktopLogin)
		if err != nil {
			logger.Warning(err)
		}
		s.SetBoolean(gsKeyDesktopLogout, soundEffect.DesktopLogout)
		s.SetBoolean(gsKeyDeviceAdded, soundEffect.DeviceAdded)
		s.SetBoolean(gsKeyDeviceRemoved, soundEffect.DeviceRemoved)
		s.SetBoolean(gsKeyDialogErrorCritical, soundEffect.DialogErrorCritical)
		s.SetBoolean(gsKeyDialogError, soundEffect.DialogError)
		s.SetBoolean(gsKeyDialogErrorSerious, soundEffect.DialogErrorSerious)
		s.SetBoolean(gsKeyMessage, soundEffect.Message)
		s.SetBoolean(gsKeyPowerPlug, soundEffect.PowerPlug)
		s.SetBoolean(gsKeyPowerUnplug, soundEffect.PowerUnplug)
		s.SetBoolean(gsKeyPowerUnplugBatteryLow, soundEffect.PowerUnplugBatteryLow)
		s.SetBoolean(gsKeyScreenCaptureComplete, soundEffect.ScreenCaptureComplete)
		s.SetBoolean(gsKeyScreenCapture, soundEffect.ScreenCapture)
		s.SetBoolean(gsKeySuspendResume, soundEffect.SuspendResume)
		s.SetBoolean(gsKeySystemShutdown, soundEffect.SystemShutdown)
		s.SetBoolean(gsKeyTrashEmpty, soundEffect.TrashEmpty)
		s.SetBoolean(gsKeyXDeepinAppSentToDesktop, soundEffect.XDeepinAppSentToDesktop)
		s.Unref()
	}
	return nil
}

// syncConfigToSoundThemePlayer 同步配置到音效主题播放器
// enabled: 是否启用桌面登录音效
// 通过DBus接口设置音效主题播放器的桌面登录音效状态
func (sc *syncConfig) syncConfigToSoundThemePlayer(enabled bool) error {
	sysBus, err := dbus.SystemBus()
	if err != nil {
		return err
	}
	player := soundthemeplayer.NewSoundThemePlayer(sysBus)
	return player.EnableSoundDesktopLogin(0, enabled)
}
