package main

import (
	"encoding/json"
	"fmt"
	"strings"
	"time"

	"git.openpdu.org/OpenPDU/openpdu/board"
	"git.openpdu.org/OpenPDU/openpdu/mqtt"
	"git.openpdu.org/OpenPDU/openpdu/outlet"
	"git.openpdu.org/OpenPDU/openpdu/syslog"
	"git.openpdu.org/OpenPDU/openpdu/webui"
	"github.com/spf13/viper"
)

func CreateOutlets() {

	outletsConfig := viper.Sub("outlets")
	if outletsConfig == nil {
		syslog.Warning("No outlet configured")
		return
	}

	outlet.Outlets = make([]*outlet.Outlet, len(board.AllChannels))

	for key := range outletsConfig.AllSettings() {
		outletConfig := outletsConfig.Sub(key)
		num := outletConfig.GetUint("num")
		outletConfig.SetDefault("description", "no description")
		description := outletConfig.GetString("description")
		channelID := strings.ToLower(outletConfig.GetString("channelID"))
		channel := board.AllChannels[channelID]
		// TODO: channel non esistente
		o := outlet.Outlet{
			ID:          key,
			Num:         num,
			Description: description,
			Channel:     channel,
		}

		outlet.Outlets[num] = &o
	}
}

func init() {
	webui.SetMQTTReconfigFunction(MQTTreconfigure)
	// mqtt.MQTTReconfig = MQTTreconfigure()
}

func MQTTSetup() {
	mqtt.Setup()
	for o := range outlet.Outlets {
		c := outlet.Outlets[o].Channel
		topic := c.MQTTCommandTopic()
		if topic == "" {
			continue
		}
		mqtt.Subscribe(topic, c.MQTTHandler)
		hAssTopic := "homeassistant/switch/" + viper.GetString("Mqtt.Prefix") + "/" + fmt.Sprint(o) + "/config"
		v := ""
		if viper.GetBool("Mqtt.HomeAssistant") {
			cfg := map[string]interface{}{
				"name":          outlet.Outlets[o].Description,
				"state_topic":   viper.GetString("Mqtt.Prefix") + "/switch/" + c.MQTTStateTopic(),
				"command_topic": viper.GetString("Mqtt.Prefix") + "/switch/" + c.MQTTCommandTopic(),
				"payload_off":   "off",
				"payload_on":    "on",
				"avty_t":        viper.GetString("Mqtt.Prefix") + "/" + viper.GetString("Mqtt.LWTTopic"),
				"pl_avail":      viper.GetString("Mqtt.LWTMessageOnline"),
				"pl_not_avail":  viper.GetString("Mqtt.LWTMessageOffline"),
				"unique_id":     viper.GetString("Mqtt.Prefix") + "_" + fmt.Sprint(o),
				"device": map[string]interface{}{
					"identifiers": []string{viper.GetString("Mqtt.Prefix")},
					// "name":         viper.GetString("system.hostname"),
					// "model":        "OpenPDU",
					// "sw_version":   version,
					// "manufacturer": "OpenPDU",
				},
			}

			s, err := json.Marshal(cfg)
			if err != nil {
				v = ""
			} else {
				v = string(s)
			}
		}
		mqtt.PublishRoot(hAssTopic, v)
	}

	hAssTopic := "homeassistant/switch/" + viper.GetString("Mqtt.Prefix") + "/config"
	v := ""
	if viper.GetBool("Mqtt.HomeAssistant") {
		cfg := map[string]interface{}{
			"name":         viper.GetString("system.hostname"),
			"avty_t":       viper.GetString("Mqtt.Prefix") + "/" + viper.GetString("Mqtt.LWTTopic"),
			"pl_avail":     viper.GetString("Mqtt.LWTMessageOnline"),
			"pl_not_avail": viper.GetString("Mqtt.LWTMessageOffline"),
			"unique_id":    viper.GetString("Mqtt.Prefix"),
			"device": map[string]interface{}{
				"identifiers":  []string{viper.GetString("Mqtt.Prefix")},
				"name":         viper.GetString("system.hostname"),
				"model":        "OpenPDU",
				"sw_version":   version,
				"manufacturer": "OpenPDU",
			},
		}

		s, err := json.Marshal(cfg)
		if err != nil {
			v = ""
		} else {
			v = string(s)
		}
	}
	mqtt.PublishRoot(hAssTopic, v)

}

func MQTTreconfigure() {
	if mqtt.Connected() {
		mqtt.Disconnect()
	}
	MQTTSetup()
}

func MQTTRefreshLoop() {
	for {
		if mqtt.Connected() {
			for o := range outlet.Outlets {
				topic := outlet.Outlets[o].Channel.MQTTStateTopic()
				value := outlet.Outlets[o].Channel.ToString()
				mqtt.Publish(topic, value)
			}
		}
		time.Sleep(30 * time.Second)
	}
}
