package main

import (
	"flag"
	"fmt"
	"io"
	"log"
	"net/http"
	"os"
	"path"
	"time"

	"github.com/loveuer/nf"
	"github.com/loveuer/nf/nft/resp"
)

var (
	addr     string
	hostname string
	root     string
)

func init() {
	flag.StringVar(&addr, "addr", ":80", "")
	flag.StringVar(&root, "root", "/data", "save file root dir")
	flag.Parse()

	hostname = os.Getenv("HOSTNAME")
	if hostname == "" {
		hostname = fmt.Sprintf("unknown-%d", time.Now().UnixNano())
	}
}

func main() {
	app := nf.New()

	app.Use(func(c *nf.Ctx) error {
		c.SetHeader("U-HOSTNAME", hostname)
		return c.Next()
	})

	app.Get("/echo/file", func(c *nf.Ctx) error {
		type Req struct {
			Filename string `query:"filename"`
			Download bool   `query:"download"`
		}

		var (
			err  error
			req  = new(Req)
			file *os.File
			bs   []byte
		)

		if err = c.QueryParser(req); err != nil {
			return resp.Resp400(c, err.Error())
		}

		if req.Filename == "" {
			return resp.Resp400(c, req, "empty file name")
		}

		filename := path.Join(root, path.Base(req.Filename))

		if file, err = os.Open(filename); err != nil {
			return resp.Resp400(c, nf.Map{"filepath": filename, "err": err.Error()})
		}

		if bs, err = io.ReadAll(file); err != nil {
			return resp.Resp400(c, nf.Map{"filepath": filename, "err": err.Error()})
		}

		ct := ""
		if len(bs) > 512 {
			ct = http.DetectContentType(bs[:512])
		} else {
			ct = http.DetectContentType(bs)
		}

		c.SetHeader("Content-Type", ct)

		_, err = c.Write(bs)

		return err
	})

	app.Post("/echo/file", func(c *nf.Ctx) error {
		type Req struct {
			Filename string
			Content  string
		}

		var (
			err  error
			req  = new(Req)
			file *os.File
		)

		if err = c.BodyParser(req); err != nil {
			return resp.Resp400(c, err.Error())
		}

		filename := path.Join(root, path.Base(req.Filename))

		if file, err = os.OpenFile(filename, os.O_CREATE|os.O_TRUNC|os.O_RDWR, 0644); err != nil {
			return resp.Resp400(c, err.Error())
		}

		defer file.Close()

		if _, err = file.WriteString(req.Content); err != nil {
			return resp.Resp500(c, err.Error())
		}

		return resp.Resp200(c, nf.Map{"filename": filename})
	})

	log.Fatal(app.Run(addr))
}