package main

import (
	"flag"
	"fmt"
	"io/ioutil"
	"net/http"
	"os"
	"strings"
	"time"

	"github.com/prometheus/client_golang/prometheus"
	"github.com/prometheus/client_golang/prometheus/promhttp"
	"github.com/prometheus/common/log"

	zkLog "log"
)

const (
	metricsRoute = "/metrics"
	probeRoute   = "/kafka"
)

var (
	version = "unknown"

	listenAddress = flag.String("web.listen-address", ":9381", "Address to listen on for web interface and telemetry.")
	serverTimeout = flag.Duration("web.timeout", 60*time.Second, "Timeout for responding to HTTP requests.")
	zkTimeout     = flag.Duration("zk.timeout", 5*time.Second, "Timeout for ZooKeeper requests")
	showVersion   = flag.Bool("version", false, "Show version and exit")
)

func handler(w http.ResponseWriter, r *http.Request) {
	zookeeper := r.URL.Query().Get("zookeeper")
	if zookeeper == "" {
		http.Error(w, "'zookeeper' parameter must be specified", 400)
		return
	}

	chroot := r.URL.Query().Get("chroot")

	topic := r.URL.Query().Get("topic")
	topics := []string{}
	if topic != "" {
		topics = strings.Split(topic, ",")
	}

	consumer := r.URL.Query().Get("consumer")
	consumers := []string{}
	if consumer != "" {
		consumers = strings.Split(consumer, ",")
	}

	registry := prometheus.NewRegistry()
	registry.MustRegister(newCollector(zookeeper, chroot, topics, consumers))

	h := promhttp.HandlerFor(registry, promhttp.HandlerOpts{})
	h.ServeHTTP(w, r)
}

func main() {
	flag.Parse()

	if *showVersion {
		fmt.Println(version)
		os.Exit(0)
	}

	// kazoo uses ZooKeeper client that logs everything by default, so we end up
	// with duplicated logs we don't control, disable vanilla logger messages
	// and rely on logs generated by our code
	zkLog.SetOutput(ioutil.Discard)

	http.Handle(metricsRoute, promhttp.Handler())
	http.HandleFunc(probeRoute, handler)
	http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
		w.Write([]byte(`
		<html>
		<head><title>Kafka ZooKeeper Exporter</title></head>
		<body>
		<p><a href='` + metricsRoute + `'>Metrics</a></p>
		<p><a href='` + probeRoute + `?zookeeper=zookeeper1.local:2181&chroot=/path'>Example Kafka ZooKeeper probe</a></p>
		</body>
		</html>
		`))
	})

	log.Infoln("Listening on", *listenAddress)

	s := &http.Server{
		Addr:         *listenAddress,
		ReadTimeout:  *serverTimeout,
		WriteTimeout: *serverTimeout,
	}
	log.Fatal(s.ListenAndServe())
}
