package captcha

import (
	"errors"
	"fmt"
	"github.com/dchest/captcha"
	"net/http"
	"netoik.io/netoik-website/pkg/api"
	"netoik.io/netoik-website/pkg/conf"
	"os"
	"path/filepath"
	"time"
)

func writeImage(id string) bool {
	path := filepath.Join(conf.Conf.CaptchaDirectory, id+".png")
	file, err := os.Create(path)
	if err != nil {
		fmt.Fprintf(os.Stderr, "ERROR: cannot write file %q: %s\n", path, err.Error())
		return false
	}
	if err = captcha.WriteImage(file, id, conf.Conf.CaptchaWidth, conf.Conf.CaptchaHeight); err != nil {
		fmt.Fprintf(os.Stderr, "ERROR: cannot write captcha into file %q: %s\n", path, err.Error())
		return false
	}
	return true
}

func HandleNew(w http.ResponseWriter, r *http.Request) {
	// Check method
	if r.Method != "POST" {
		api.Reply(w, 405, api.Answer{})
		return
	}

	// Create new captcha
	id := captcha.NewLen(conf.Conf.CaptchaLength)

	// Write captcha image
	if !writeImage(id) {
		api.Reply(w, 500, api.Answer{})
		return
	}

	// Remove captcha image after expiration time
	go func(id string) {
		time.Sleep(conf.Conf.CaptchaExpiration)
		path := filepath.Join(conf.Conf.CaptchaDirectory, id+".png")
		if err := os.Remove(path); err != nil && !errors.Is(err, os.ErrNotExist) {
			fmt.Fprintf(os.Stderr, "ERROR: cannot remove captcha image after expiration %q: %s", path, err.Error())
		}
	}(id)

	// Return captcha id
	api.Reply(w, 200, api.Answer{Success: true, Id: id})
}

func Setup() {
	captcha.SetCustomStore(captcha.NewMemoryStore(captcha.CollectNum, conf.Conf.CaptchaExpiration))
}
