package dispatcher

import "log"
import "udi/mqtt"
import "udi/config"
import "udi/handlers/handler"
import "udi/handlers/ttn"


var handlerMap map[string]handler.Handler = make(map[string]handler.Handler)
var archiverChannel chan mqtt.Message = make(chan mqtt.Message, 100)

func InitDispatcher() {
  log.Printf("Initializing dispatcher")
  go archiver()
  for _, handlerEntry := range config.Config.Handlers {
    log.Printf("Trying %s", handlerEntry.Name)
    switch handlerEntry.Name {
    case "TTN":
      handlerMap[handlerEntry.Name] = ttn.NewTTNHandler()
      log.Printf("TTN initialized")
    default:
      log.Fatalf("Handler %s not found", handlerEntry.Name)
    }
  }
}

func archiver() {
  for {
    select {
    case _ = <- archiverChannel:
      log.Printf("Archiving message")
    }
  }
}

func InputDispatcher() {
  for {
    select {
    case message := <- mqtt.InputChannel:
      log.Printf("Message arrived in inputDispatcher, topic: %s\n", message.Topic)
      archiverChannel <- message

      for _, mapping := range config.Config.TopicMappings {
        log.Printf("Testing %s -> %s", mapping.Topics, mapping.Handler)
        for _, subscribedTopic := range mapping.Topics {
          log.Printf("Testing %s in %s", message.Topic, subscribedTopic)
          if mqtt.TopicMatchesSubscription(message.Topic, subscribedTopic) {
            log.Printf("Handle message in handler %s", mapping.Handler)
            handler, exists := handlerMap[mapping.Handler]
            if exists {
              handler.Handle(message.Topic, string(message.Payload))
            } else {
              log.Printf("Handler not found, message is lost")
            }
          } else {
            log.Printf("no match")
          }
        }
      }
    }
  }
}