package main

import (
	"encoding/json"
	"log"
	endpoint "monitoring/app/routers/metrics"
	increment "monitoring/app/routers/metrics"
	task "monitoring/app/routers/metrics"
	client "monitoring/app/storage/clickhouse"
	endpoints "monitoring/app/storage/clickhouse/tables"
	"net/http"
	"os"
	"time"
)

func writeMetric(timestamp time.Time, endpoint string, statusCode int, responseTime int, method string) {
	endpoints.AddEndpointMetric(client.EndpointMetric{
		Timestamp:    timestamp.Add(time.Hour * 3),
		Service:      "monitoring",
		Environment:  os.Getenv("STAGE"),
		Endpoint:     endpoint,
		StatusCode:   statusCode,
		ResponseTime: responseTime,
		Method:       method,
	})
}

func handlerWrapper(f func(*http.Request) (interface{}, int)) func(http.ResponseWriter, *http.Request) {
	return func(w http.ResponseWriter, r *http.Request) {
		start := time.Now()
		response, status := f(r)
		if response != nil {
			data, err := json.Marshal(response)
			if err != nil {
				log.Printf("Error marshalling response")
				status = http.StatusInternalServerError
			}
			w.WriteHeader(status)
			w.Write(data)
		} else {
			w.WriteHeader(status)
		}
		go writeMetric(start, r.URL.Path, status, int(time.Since(start).Milliseconds()), r.Method)
		log.Printf("%s %d %s", r.URL, status, time.Since(start))
	}
}

func main() {
	err := client.Connect()
	if err != nil {
		panic(err)
	}
	defer client.Close()

	err = client.Migrate()
	if err != nil {
		panic(err)
	}

	http.HandleFunc("/api/v1/metrics/endpoint", handlerWrapper(endpoint.AddEndpointMetric))
	http.HandleFunc("/api/v1/metrics/task", handlerWrapper(task.AddTaskMetric))
	http.HandleFunc("/api/v1/metrics/increment", handlerWrapper(increment.AddIncrementMetric))
	log.Printf("Server started")
	http.ListenAndServe(":1237", nil)
}
