package snmp

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

	"smq/config"
	"smq/mqtt"

	"github.com/gosnmp/gosnmp"
)

type variable_t struct {
  Label string `json:"label"`
  Variable string `json:"variable"`
  Value string `json:"value"`
}

type message_t struct {
  Device string `json:"device"`
  Label string `json:"label"`
  Variables map[string]variable_t `json:"variables"`
}


func Start() {
	for {
    for _, endpoint := range config.Config.SNMPEndpoints {
      log.Println("Polling endpoint " + endpoint.Endpoint)

      snmp := gosnmp.GoSNMP{}

      snmp.Target = endpoint.Endpoint
      snmp.Port = 161
      snmp.Version = gosnmp.Version2c
      snmp.Community = endpoint.Community

      snmp.Timeout = time.Duration(5 * time.Second)
      err := snmp.Connect()
      if err != nil {
        log.Fatal("SNMP Connect error\n")
      }

      oids := []string{}

      for _, oidTopic := range endpoint.OIDTopics {
        oids = append(oids, oidTopic.OID)
      }

      result, err := snmp.Get(oids)
      if err != nil {
        log.Printf("error in Get: %s", err)
      } else {
        message := message_t {
          Device: endpoint.Endpoint,
          Label: endpoint.Label,
          Variables: make(map[string]variable_t),
        }
        

        for _, variable := range result.Variables {
          for _, oidTopic := range endpoint.OIDTopics {
            if oidTopic.OID == variable.Name {
              convertedValue := ""

              switch variable.Type {
              case gosnmp.OctetString:
                convertedValue = string(variable.Value.([]byte))
              default:
                convertedValue = fmt.Sprintf("%d", gosnmp.ToBigInt(variable.Value))
              }

              log.Printf("%s = %s", oidTopic.OID, convertedValue)
              v := variable_t {
                Label: oidTopic.Label,
                Variable: oidTopic.OID,
                Value: convertedValue,
              }
              message.Variables[oidTopic.Label] = v

              // build topic and payload and push into the mqtt.OutputChannel
            }
          }
        }

        j, err := json.Marshal(message)
        if err != nil {
          log.Printf("Unable to marshal message, it is lost: %s, %v", message, err)
        } else {
          mqtt.Publish(j)
        }
      }
      snmp.Conn.Close()
    }

		time.Sleep(time.Duration(config.Config.Interval) * time.Second)
	}
}

func Stop() {
}
