package routers

import (
	"context"
	"fmt"
	"log"
	"net/http"
	"strconv"

	"git.paulbsd.com/paulbsd/ipbl/src/config"
	"git.paulbsd.com/paulbsd/ipbl/src/models"

	"github.com/labstack/echo/v4"
)

func RegisterRoutes(e *echo.Echo, ctx *context.Context, cfg *config.Config) {
	e.GET("/", func(c echo.Context) error {
		return c.HTML(http.StatusOK, `<html>
		<body>
		<p>Welcome to ipbl software (<a href="https://git.paulbsd.com/paulbsd/ipbl">https://git.paulbsd.com/paulbsd/ipbl</a>)</p>
		</body>
		</html>`)
	})

	e.GET("/ip/:ip", func(c echo.Context) (err error) {
		ret, err := models.GetIP(ctx, cfg, c.Param("ip"))
		return Result(c, err, ret)
	})
	e.POST("/ip", func(c echo.Context) (err error) {
		var ip = new(models.IP)
		var msg = "No IP inserted"
		err = c.Bind(ip)
		if err != nil {
			return Result(c, fmt.Errorf("error when parsing body"), "")
		}
		numinsert, numupdate, err := ip.InsertOrUpdate(cfg)
		if err != nil {
			return Result(c, err, "")
		}
		msg = fmt.Sprintf("zmq: Inserted %d IP, Updated %d IP", numinsert, numupdate)
		log.Println(msg)
		return Result(c, err, msg)
	})
	e.GET("/ips", func(c echo.Context) (err error) {
		limit := 50
		if c.QueryParam("limit") != "" {
			limit, _ = strconv.Atoi(c.QueryParam("limit"))
		}
		ret, err := models.GetIPs(ctx, cfg, limit)
		return Result(c, err, ret)
	})
	e.GET("/ips/last", func(c echo.Context) (err error) {
		interval := "30m"
		if c.QueryParam("interval") != "" {
			interval = c.QueryParam("interval")
		}
		ret, err := models.GetIPsLast(ctx, cfg, interval)
		return Result(c, err, ret)
	})
	e.POST("/ips", func(c echo.Context) (err error) {
		var apiips = []models.APIIP{}
		var ips = []models.IP{}
		var msg string
		err = c.Bind(&apiips)
		if err != nil {
			return Result(c, err, apiips)
		}
		for _, apiip := range apiips {
			ips = append(ips, *apiip.APIConvert())
		}
		numinsert, numupdate, _ := models.InsertIPBulk(cfg, &ips)
		msg = fmt.Sprintf("zmq: Inserted %d IP, Updated %d IP", numinsert, numupdate)
		log.Println(msg)
		return Result(c, err, msg)
	})
	e.POST("/hostinfo", func(c echo.Context) (err error) {
		var hostinfo = models.HostInfo{}
		err = c.Bind(&hostinfo)
		if err != nil {
			return Result(c, err, hostinfo)
		}
		num, err := cfg.Db.Insert(&hostinfo)
		msg := fmt.Sprintf("Inserted %v host info (%d)", hostinfo, num)
		log.Println(msg)
		return Result(c, err, msg)
	})
	e.GET("/config", func(c echo.Context) (err error) {
		trustlists, err := models.GetGlobalConfig(*cfg)
		return Result(c, err, trustlists)
	})
	e.GET("/config/trustlist", func(c echo.Context) (err error) {
		trustlists, err := models.GetTrustlists(*cfg)
		return Result(c, err, trustlists)
	})
	e.POST("/config/trustlist", func(c echo.Context) (err error) {
		var cidr models.CfgTrustlist
		err = c.Bind(&cidr)
		if err == nil && cidr.Verify() {
			err = cidr.InsertOrUpdate(*cfg)
			return Result(c, err, cidr)
		}
		return Result(c, err, nil)
	})
	e.DELETE("/config/trustlist/:ip", func(c echo.Context) (err error) {
		var ip = c.Param("ip")
		var cidr models.CfgTrustlist
		_, err = cidr.Delete(*cfg, ip)
		return
	})
	e.GET("/config/sets", func(c echo.Context) (err error) {
		sets, err := models.GetSets(*cfg)
		return Result(c, err, sets)
	})
	e.GET("/config/zmq", func(c echo.Context) (err error) {
		folders, err := models.GetZMQ(*cfg)
		return Result(c, err, folders)
	})
	e.GET("/discovery", func(c echo.Context) (err error) {
		disc, err := models.DiscoverURLS(*cfg, e.Routes())
		return Result(c, err, disc)
	})
}
