package globals

import (
	"netease_control_center/interfaces/log"
	"netease_control_center/utils"
	"netease_control_center/utils/godbus/dbus"
	"os/exec"
	"strings"
	"time"
)

type ModInfo struct {
	Path           string
	Aliase         string
	MethodMap      *map[string]interface{}
	Init           bool
	SignalChan     chan *dbus.Signal
	Online         bool
	LastOnlineTime time.Time

	NeedSeqHandle  bool
	SeqSigHandFunc func(message *dbus.Signal)
}

const (
	MODULE_CONTROLLER = iota
	MODULE_ALARM
	MODULE_CALL
	MODULE_VOICEENGINE
	MODULE_PLAYER
	MODULE_CONFIGURE
	MODULE_OTA
	MODULE_WIFI
	MODULE_BT
	MODULE_DLNA
	MODULE_DLNA_TEST // 占位符
	MODULE_AIRPLAY
	MODULE_AIRPLAY_TEST
	MODULE_LIGHT_MCU
	MODULE_BLUEKC
	MODULE_BLUEKC_TEST
	MODULE_MANUFACTURE
	MODULE_BT_DEMO
	MODULE_SKINS
	MODULE_LOG_CTRL
	MODULE_WIRELESSTEST
	MODULE_WIRELESSTEST_DEMO
	MODULE_MANUFACTURE_CONTROLLER
	MODULE_MAX
	MODULE_ERROR
)

var (
	Modules = map[uint32]*ModInfo{
		MODULE_CALL:                   &ModInfo{Path: "/netease/ihw/call", Aliase: "netease.ihw.call", Init: false},
		MODULE_VOICEENGINE:            &ModInfo{Path: "/netease/ihw/voice_engine", Aliase: "netease.ihw.voice_engine", Init: false},
		MODULE_PLAYER:                 &ModInfo{Path: "/netease/ihw/player", Aliase: "netease.ihw.player", Init: false},
		MODULE_WIFI:                   &ModInfo{Path: "/netease/ihw/wifi", Aliase: "netease.ihw.wifi", Init: false},
		MODULE_BT:                     &ModInfo{Path: "/netease/ihw/bt", Aliase: "netease.ihw.bt", Init: false},
		MODULE_OTA:                    &ModInfo{Path: "/netease/ihw/ota", Aliase: "netease.ihw.ota", Init: false},
		MODULE_ALARM:                  &ModInfo{Path: "/netease/ihw/alarm", Aliase: "netease.ihw.alarm", Init: false},
		MODULE_DLNA:                   &ModInfo{Path: "/netease/ihw/kplayer", Aliase: "netease.ihw.kplayer", Init: false},
		MODULE_AIRPLAY:                &ModInfo{Path: "/netease/ihw/splayer", Aliase: "netease.ihw.splayer", Init: false},
		MODULE_MANUFACTURE:            &ModInfo{Path: "/netease/ihw/manufacture", Aliase: "netease.ihw.manufacture", Init: false},
		MODULE_MANUFACTURE_CONTROLLER: &ModInfo{Path: "/netease/ihw/manufacture_controller", Aliase: "netease.ihw.manufacture_controller", Init: false},
	}
)

func (this *ModInfo) GetModuleId() uint32 {
	for k, v := range Modules {
		if v.Path == this.Path {
			return k
		}
	}

	return MODULE_ERROR
}

func (this *ModInfo) GetModuleShFilePath() string {
	switch this.GetModuleId() {
	case MODULE_PLAYER:
		return "/etc/init.d/netease_player_service"

	case MODULE_VOICEENGINE:
		return "/etc/init.d/netease_voice_service"

	case MODULE_WIFI:
		return "/etc/init.d/netease_wifi_service"

	case MODULE_AIRPLAY, MODULE_DLNA, MODULE_ALARM, MODULE_OTA, MODULE_BT:
		return "/etc/init.d/netease_services"
	}

	return ""
}

func (this *ModInfo) ServiceRestart() {
	if path := this.GetModuleShFilePath(); len(path) > 0 {
		exec.Command("/bin/sh", "-c", path+" restart").Start()
		log.Println(log.DebugLog, "Restart ", this.Aliase, path)
	} else {
		log.Println(log.ErrorLog, "Get path error")
	}
}

func (this *ModInfo) ServiceStart() {
	if path := this.GetModuleShFilePath(); len(path) > 0 {
		exec.Command("/bin/sh", "-c", path+" start").Start()
		log.Println(log.DebugLog, "Start ", this.Aliase)
	} else {
		log.Println(log.ErrorLog, "Get path error")
	}
}

func (this *ModInfo) ServiceStop() {
	if path := this.GetModuleShFilePath(); len(path) > 0 {
		exec.Command("/bin/sh", "-c", path+" stop").Start()
		log.Println(log.DebugLog, "Stop ", this.Aliase)
	} else {
		log.Println(log.ErrorLog, "Get path error")
	}
}

func ADBControl(on bool) {
	if on {
		exec.Command("/bin/sh", "-c", "/etc/init.d/adbd start").Start()
	} else {
		exec.Command("/bin/sh", "-c", "/etc/init.d/adbd stop").Start()
	}
}

func ProcessOn(name string) bool {
	data, _ := exec.Command("ps").CombinedOutput()
	return strings.Contains(string(data), name)
}

func CheckAdb() {
	if !utils.PathExist("/mnt/UDISK/disableadb") {
		log.Println(log.DebugLog, "ADB on!")
		if !ProcessOn("adbd") {
			ADBControl(true)
		}
	} else {
		log.Println(log.DebugLog, "ADB STOP!")
		ADBControl(false)
	}
}

func (this *ModInfo) Start() {

}

func (this *ModInfo) Stop() {

}

func GetAllModules() *map[uint32]*ModInfo {
	return &Modules
}

func SetModOnlineByModid(modid uint32) {
	if val, ok := Modules[modid]; ok {
		val.Online = true
		val.LastOnlineTime = time.Now()
	}
}

func SetModOnlineByPath(path string) {
	for _, val := range Modules {
		if val.Path == path {
			val.Online = true
			val.LastOnlineTime = time.Now()
		}
	}
}

func IsModOnline(modid uint32) bool {
	if val, ok := Modules[modid]; ok {
		return val.Online
	} else {
		return false
	}
}

func ClearModOnline(modid uint32) {
	if val, ok := Modules[modid]; ok {
		val.Online = false
	}
}
