// Copyright (C) 2020 Marius Schellenberger

package syspatch

import (
	"bytes"
	"github.com/go-kit/kit/log"
	"github.com/go-kit/kit/log/level"
	"github.com/prometheus/client_golang/prometheus"
	"os/exec"
	"sync"
	"time"
)

const (
	namespace = "syspatch"
	syspatch  = "/usr/sbin/syspatch"

	errUpdateInterval = time.Second * 30
	updateInterval    = time.Hour * 2
)

type Collector struct {
	sync.RWMutex
	patches *prometheus.Desc
	logger  log.Logger

	num float64
}

// NewCollector returns a new Collector exposing rcctl statistics.
func NewCollector(logger log.Logger) (*Collector, error) {
	c := &Collector{
		patches: prometheus.NewDesc(
			prometheus.BuildFQName(namespace, "", "patches_available"),
			"Number of syspatch patches available.",
			nil, nil,
		),
		logger: logger,
	}
	go c.getPatches()
	return c, nil
}

func (c *Collector) getPatches() {
	for {
		cmd := exec.Command(syspatch, "-c")
		out, err := cmd.Output()
		if err != nil {
			level.Debug(c.logger).Log("msg", "syspatch list patches", "error", err)
			time.Sleep(errUpdateInterval)
			continue
		}
		num := float64(bytes.Count(out, []byte("\n")))
		c.Lock()
		c.num = num
		c.Unlock()
		time.Sleep(updateInterval)
	}
}

func (c *Collector) Collect(ch chan<- prometheus.Metric) {
	c.RLock()
	num := c.num
	c.RUnlock()
	ch <- prometheus.MustNewConstMetric(
		c.patches, prometheus.GaugeValue, num)
}

func (c *Collector) Describe(desc chan<- *prometheus.Desc) {
	desc <- c.patches
}
