package main

import (
	"fmt"
	"github.com/prometheus/client_golang/prometheus"
	"github.com/prometheus/client_golang/prometheus/promhttp"
	"github.com/sirupsen/logrus"
	"github.com/yitsushi/go-misskey"
	"net/http"
	"os"
)

//TIP <p>To run your code, right-click the code and select <b>Run</b>.</p> <p>Alternatively, click
// the <icon src="AllIcons.Actions.Execute"/> icon in the gutter and select the <b>Run</b> menu item from here.</p>

//var now = time.Now()

var client *misskey.Client
var endpoint = os.Getenv("MISSKEY_ENDPOINT")
var protocol, hasProtocolEnv = os.LookupEnv("MISSKEY_PROTOCOL")
var path = os.Getenv("MISSKEY_PATH")
var apiKey = os.Getenv("MISSKEY_API_TOKEN")

var (
	misskeyJobQueueJobsCount = prometheus.NewGaugeVec(
		prometheus.GaugeOpts{
			Name: "misskey_jobqueue_jobs",
			Help: "misskey job queue jobs",
		},
		[]string{"type", "status"},
	)
	misskeyNotesCount = prometheus.NewGauge(
		prometheus.GaugeOpts{
			Name: "misskey_notes_count",
			Help: "Notes Coount",
		},
	)
	misskeyUsersCount = prometheus.NewGauge(
		prometheus.GaugeOpts{
			Name: "misskey_users_count",
			Help: "Users Coount",
		},
	)
	misskeyOriginalNotesCount = prometheus.NewGauge(
		prometheus.GaugeOpts{
			Name: "misskey_original_notes_count",
			Help: "Original Notes Coount",
		},
	)
	misskeyOriginalUsersCount = prometheus.NewGauge(
		prometheus.GaugeOpts{
			Name: "misskey_original_users_count",
			Help: "Original Users Coount",
		},
	)
	misskeyPingResponseTimeRaw = prometheus.NewGauge(
		prometheus.GaugeOpts{
			Name: "misskey_ping_response_time_raw",
			Help: "Response Time for misskey Ping",
		},
	)
	misskeyPingResponseTime = prometheus.NewHistogram(
		prometheus.HistogramOpts{
			Name:    "misskey_ping_response_time",
			Help:    "Response Time for misskey Ping",
			Buckets: prometheus.DefBuckets,
		},
	)
	misskeyPingResponseCode = prometheus.NewGauge(
		prometheus.GaugeOpts{
			Name: "misskey_ping_response_code",
			Help: "Response Code for misskey Ping",
		},
	)
	misskeyGlobalTimelineResponseTime = prometheus.NewHistogram(
		prometheus.HistogramOpts{
			Name: "misskey_global_timeline_response_time",
			Help: "Response Time for misskey Global Timeline",
		})
	misskeyLocalTimelineResponseTime = prometheus.NewHistogram(
		prometheus.HistogramOpts{
			Name: "misskey_local_timeline_response_time",
			Help: "Response Time for misskey Local Timeline",
		})
	misskeyGlobalTimelineLastNotePublished = prometheus.NewGauge(
		prometheus.GaugeOpts{
			Name: "misskey_global_timeline_last_note_published",
			Help: "Last Note Published on Global Timeline",
		})
	misskeyLocalTimelineLastNotePublished = prometheus.NewGauge(
		prometheus.GaugeOpts{
			Name: "misskey_local_timeline_last_note_published",
			Help: "Last Note Published on Local Timeline",
		})
	misskeyGlobalTimelineResponseTimeRaw = prometheus.NewGauge(
		prometheus.GaugeOpts{
			Name: "misskey_global_timeline_response_time_raw",
			Help: "Response Time for misskey Global Timeline",
		})
	misskeyLocalTimelineResponseTimeRaw = prometheus.NewGauge(
		prometheus.GaugeOpts{
			Name: "misskey_local_timeline_response_time_raw",
			Help: "Response Time for misskey Local Timeline",
		})
	misskeyHomeTimelineResponseTime = prometheus.NewHistogram(
		prometheus.HistogramOpts{
			Name: "misskey_home_timeline_response_time",
			Help: "Response Time for misskey Home Timeline",
		})
	misskeyHomeTimelineResponseTimeRaw = prometheus.NewGauge(
		prometheus.GaugeOpts{
			Name: "misskey_home_timeline_response_time_raw",
			Help: "Response Time for misskey Home Timeline",
		})
	misskeyHomeTimelineLastNotePublished = prometheus.NewGauge(
		prometheus.GaugeOpts{
			Name: "misskey_home_timeline_last_note_published",
			Help: "Last Note Published on Home Timeline",
		},
	)
	misskeySocialTimelineResponseTime = prometheus.NewHistogram(
		prometheus.HistogramOpts{
			Name: "misskey_social_timeline_response_time",
			Help: "Response Time for misskey Home Timeline",
		})
	misskeySocialTimelineResponseTimeRaw = prometheus.NewGauge(
		prometheus.GaugeOpts{
			Name: "misskey_social_timeline_response_time_raw",
			Help: "Response Time for misskey Home Timeline",
		})
	misskeySocialTimelineLastNotePublished = prometheus.NewGauge(
		prometheus.GaugeOpts{
			Name: "misskey_social_timeline_last_note_published",
			Help: "Last Note Published on Home Timeline",
		},
	)
	misskeyApiResponseTime = prometheus.NewHistogramVec(
		prometheus.HistogramOpts{
			Name:    "misskey_api_response_time",
			Help:    "Response Time for misskey API",
			Buckets: prometheus.DefBuckets,
		},
		[]string{"type", "api"},
	)
	misskeyApiResponseTimeRaw = prometheus.NewGaugeVec(
		prometheus.GaugeOpts{
			Name: "misskey_api_response_time_raw",
			Help: "Response Time for misskey API",
		},
		[]string{"type", "api"},
	)
	misskeyOnlineUsers = prometheus.NewGauge(
		prometheus.GaugeOpts{
			Name: "misskey_online_users",
			Help: "Online Users",
		})
	misskeyMeta = prometheus.NewGaugeVec(
		prometheus.GaugeOpts{
			Name: "misskey_meta",
			Help: "Misskey Instance Metadata",
		},
		[]string{"version"})
)

func main() {

	if !hasProtocolEnv {
		protocol = "https"
	}

	options, err := misskey.NewClientWithOptions(
		misskey.WithAPIToken(apiKey),
		misskey.WithBaseURL(protocol, endpoint, path),
		misskey.WithLogLevel(logrus.InfoLevel),
	)
	client = options
	if err != nil {
		logrus.Error(err)
		return
	}
	stats, err := client.Admin().Queue().Stats()
	if err != nil {
		logrus.Error(err)
		return
	}
	fmt.Println(stats)

	prometheus.MustRegister(misskeyJobQueueJobsCount)
	prometheus.MustRegister(misskeyNotesCount)
	prometheus.MustRegister(misskeyUsersCount)
	prometheus.MustRegister(misskeyOriginalNotesCount)
	prometheus.MustRegister(misskeyOriginalUsersCount)
	prometheus.MustRegister(misskeyPingResponseTime)
	prometheus.MustRegister(misskeyPingResponseTimeRaw)
	prometheus.MustRegister(misskeyPingResponseCode)
	prometheus.MustRegister(misskeyGlobalTimelineResponseTime)
	prometheus.MustRegister(misskeyLocalTimelineResponseTime)
	prometheus.MustRegister(misskeyGlobalTimelineLastNotePublished)
	prometheus.MustRegister(misskeyLocalTimelineLastNotePublished)
	prometheus.MustRegister(misskeyGlobalTimelineResponseTimeRaw)
	prometheus.MustRegister(misskeyLocalTimelineResponseTimeRaw)
	prometheus.MustRegister(misskeyHomeTimelineResponseTime)
	prometheus.MustRegister(misskeyHomeTimelineResponseTimeRaw)
	prometheus.MustRegister(misskeyHomeTimelineLastNotePublished)
	prometheus.MustRegister(misskeySocialTimelineResponseTime)
	prometheus.MustRegister(misskeySocialTimelineResponseTimeRaw)
	prometheus.MustRegister(misskeySocialTimelineLastNotePublished)
	prometheus.MustRegister(misskeyApiResponseTime)
	prometheus.MustRegister(misskeyApiResponseTimeRaw)
	prometheus.MustRegister(misskeyOnlineUsers)
	prometheus.MustRegister(misskeyMeta)

	handler := promhttp.Handler()

	server := http.Server{
		Addr:    ":8080",
		Handler: handler,
	}

	go func() {
		go collectJobqueue()
		go collectPing()
		go collectStats()
		go collectTimeline()
		go collectOnlineUsers()
		go collectMeta()
	}()

	logrus.Error(server.ListenAndServe())

}