package main

import (
	"bytes"
	"encoding/json"
	"html/template"
	"io/ioutil"	
	"math/rand"
	"net/http"
	"os"
	"time"
	"github.com/prometheus/client_golang/prometheus/promhttp"
	"github.com/prometheus/client_golang/prometheus"
)

type Image struct {
	Url       string `json:"url"`
	Caption   string `json:"caption"`
	Copyright string `json:"copyright"`
}

type AccessLog struct {
	ClientIP  string `json:"clientIp"`
}

func main() {
	tmpl := template.Must(template.ParseFiles("index.html"))
	imageApiUrl :=  os.Getenv("IMAGE_API_URL")
	logApiUrl := os.Getenv("ACCESS_API_URL")

	//re-use HTTP client with minimal keep-alive
	tr := &http.Transport{
		MaxIdleConns: 1,
	    IdleConnTimeout: 1 * time.Second,
	}
	client := &http.Client{Transport: tr}

	//create Prometheus metrics
	inFlightGauge := prometheus.NewGauge(prometheus.GaugeOpts{
		Name: "image_gallery_in_flight_requests",
		Help: "Image Gallery - in-flight requests",
	})
	requestCounter := prometheus.NewCounterVec(
		prometheus.CounterOpts{
			Name: "image_gallery_requests_total",
			Help: "Image Gallery - total requests",
		},
		[]string{"code", "method"},
	)

	prometheus.MustRegister(inFlightGauge, requestCounter)

	rand.Seed(time.Now().UnixNano())

	indexHandler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		response,_ := client.Get(imageApiUrl)
		defer response.Body.Close()
		data,_ := ioutil.ReadAll(response.Body)
		image := Image{}
		json.Unmarshal([]byte(data), &image)	
		tmpl.Execute(w, image)
		log := AccessLog{
			ClientIP: r.RemoteAddr,
		}
		jsonLog,_ := json.Marshal(log)
		response,_ = client.Post(logApiUrl, "application/json", bytes.NewBuffer(jsonLog))
		defer response.Body.Close()

	})

	wrappedIndexHandler := promhttp.InstrumentHandlerInFlight(inFlightGauge,
						    promhttp.InstrumentHandlerCounter(requestCounter, indexHandler))
	
	http.Handle("/", wrappedIndexHandler)
	http.Handle("/metrics", promhttp.Handler())
	
	http.ListenAndServe(":80", nil)
}