// Copyright 2015 The Vanadium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Package sysstats implements system statistics and updates them periodically.
//
// Importing this package causes the stats to be exported via an init function.
package sysstats

import (
	"os"
	"reflect"
	"runtime"
	"strings"
	"time"

	"v.io/x/lib/buildinfo"
	"v.io/x/ref/lib/stats"
)

func init() {
	now := time.Now()
	stats.NewInteger("system/start-time-unix").Set(now.Unix())
	stats.NewString("system/start-time-rfc1123").Set(now.Format(time.RFC1123))
	stats.NewString("system/cmdline").Set(strings.Join(os.Args, " "))
	stats.NewInteger("system/num-cpu").Set(int64(runtime.NumCPU()))
	stats.NewIntegerFunc("system/num-goroutine", func() int64 { return int64(runtime.NumGoroutine()) })
	stats.NewString("system/version").Set(runtime.Version())
	stats.NewInteger("system/pid").Set(int64(os.Getpid()))
	if hostname, err := os.Hostname(); err == nil {
		stats.NewString("system/hostname").Set(hostname)
	}
	stats.NewIntegerFunc("system/GOMAXPROCS", func() int64 { return int64(runtime.GOMAXPROCS(0)) })
	exportEnv()
	exportMemStats()
	exportBuildInfo()
}

func exportEnv() {
	var kv []stats.KeyValue
	for _, v := range os.Environ() {
		if parts := strings.SplitN(v, "=", 2); len(parts) == 2 {
			kv = append(kv, stats.KeyValue{parts[0], parts[1]})
		}
	}
	stats.NewMap("system/environ").Set(kv)
}

func exportMemStats() {
	mstats := stats.NewMap("system/memstats")

	// Get field names to export.
	var memstats runtime.MemStats
	fieldNames := []string{}
	v := reflect.ValueOf(memstats)
	v.FieldByNameFunc(func(name string) bool {
		switch v.FieldByName(name).Kind() {
		case reflect.Bool, reflect.Uint32, reflect.Uint64:
			fieldNames = append(fieldNames, name)
		}
		return false
	})
	updateStats := func() {
		var memstats runtime.MemStats
		runtime.ReadMemStats(&memstats)
		v := reflect.ValueOf(memstats)
		kv := make([]stats.KeyValue, len(fieldNames))
		for i, name := range fieldNames {
			kv[i] = stats.KeyValue{name, v.FieldByName(name).Interface()}
		}
		mstats.Set(kv)
	}
	// Update stats now and every 10 seconds afterwards.
	updateStats()
	go func() {
		for {
			time.Sleep(10 * time.Second)
			updateStats()
		}
	}()
}

func exportBuildInfo() {
	kv := []stats.KeyValue{}
	v := reflect.ValueOf(*buildinfo.Info())
	for i := 0; i < v.NumField(); i++ {
		kv = append(kv, stats.KeyValue{v.Type().Field(i).Name, v.Field(i).Interface()})
	}
	stats.NewMap("system/buildinfo").Set(kv)
}
