package routers

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

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

	"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>
<head></head>
<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("/health", func(c echo.Context) error {
		return c.HTML(http.StatusOK, `OK`)
	})

	e.GET("/ip/:ip", func(c echo.Context) (err error) {
		session := cfg.Db.NewSession()
		defer session.Close()
		var ip = models.IP{IP: c.Param("ip")}
		ret, err := ip.Get(session)
		return Result(c, err, ret)
	})
	e.POST("/ip", func(c echo.Context) (err error) {
		session := cfg.Db.NewSession()
		var apiip = new(models.APIIP)
		var ip = new(models.IP)
		var msg = "No IP inserted"
		err = c.Bind(apiip)
		if err != nil {
			return Result(c, fmt.Errorf("error when parsing body"), "")
		}
		ip.APIParse(*apiip)
		_, err = ip.GetOrCreate(session)
		if err != nil {
			return Result(c, err, "")
		}
		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.GET("/ips/withouthostinfo", func(c echo.Context) (err error) {
		ret, err := models.GetIPsWithoutHostInfo(ctx, cfg)
		return Result(c, err, ret)
	})
	e.POST("/ips", func(c echo.Context) (err error) {
		session := cfg.Db.NewSession()
		defer session.Close()
		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 {
			var ip = new(models.IP)
			ip.APIParse(apiip)
			ips = append(ips, *ip)
		}
		numinsert, numupdate, _ := models.InsertIPBulk(session, &ips)
		msg = fmt.Sprintf("Inserted %d IP, Updated %d IP", numinsert, numupdate)
		return Result(c, err, msg)
	})
	e.POST("/event", func(c echo.Context) (err error) {
		session := cfg.Db.NewSession()
		defer session.Close()
		var apievent = new(models.APIEvent)
		var event = new(models.Event)
		err = c.Bind(apievent)
		if err != nil {
			return Result(c, fmt.Errorf("error when parsing body"), "")
		}
		event.APIParse(session, *apievent)
		err = event.Insert(cfg)
		if err != nil {
			return Result(c, err, "")
		}
		return Result(c, err, "OK")
	})
	e.POST("/hostinfo", func(c echo.Context) (err error) {
		var hostinfos = []models.HostInfo{}
		err = c.Bind(&hostinfos)
		if err != nil {
			return Result(c, err, hostinfos)
		}
		models.ProcessHostInfo(cfg, hostinfos)
		return Result(c, err, "")
	})
	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/ws", func(c echo.Context) (err error) {
		folders, err := models.GetWS(*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)
	})
	e.File("/test.html", "/home/paul/test.html")
	e.GET("/wsps", func(c echo.Context) (err error) {
		ws.HandleWSPS(c, cfg)
		return
	})
	e.GET("/wsrr", func(c echo.Context) (err error) {
		ws.HandleWSRR(c, cfg)
		return
	})
}
