package main

import (
	"fmt"
	"image"
	_ "image/jpeg"
	_ "image/png"
	"io"
	"log"
	"os"

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

// Send an image to microservice for image analysis
func ImageRequestHandler(c echo.Context, img *os.File) error {
	// TODO: Use user image instead
	log.Print(img.Name())

	// Get filesize of image
	stat, err := img.Stat()
	log.Print("File size: ", stat.Size()/1024, " kb")

	// Get width and height in px for the image
	im, _, err := image.DecodeConfig(img)
	if err != nil {
		fmt.Fprintf(os.Stderr, "%s: %v\n", img.Name(), err)
	}
	log.Print(im.Width)

	// Form JSON response that contains name, size, height and width
	jsonStr := fmt.Sprintf(`{ "name": "%s",
				 "size": %d,
				 "width": %d,
				 "height": %d
				}`, img.Name(), stat.Size(), im.Width, im.Height)
	log.Print(jsonStr)

	c.Response().Header().Set("Content-Type", "application/json")
	//TODO: Avoid double casting []byte string?!
	c.Response().Write([]byte(string(jsonStr)))

	// TODO: Figure out how to avoid return and just return with c.Response() similar to w.Write
	return err
}

func main() {
	e := echo.New()

	// Avoid CORS error when testing with redocly
	e.Use(middleware.CORS())

	// API Versioning
	apiGroup := e.Group("/api")
	apiv1Group := apiGroup.Group("/v1")

	apiv1Group.POST("/imageanalysis", func(c echo.Context) error {
		// TODO: Catch error when no file is send in POST Request
		// Source
		file, err := c.FormFile("file")
		if err != nil {
			return err
		}
		src, err := file.Open()
		if err != nil {
			return err
		}
		defer src.Close()

		// Destination
		dst, err := os.Create(file.Filename)
		if err != nil {
			return err
		}
		defer dst.Close()

		// Copy
		if _, err = io.Copy(dst, src); err != nil {
			return err
		}
		// TODO: Why do i need to open the file here again, instead of just passing the reference from os.Create()?
		// TODO: Maybe don't create the file on disk at all, just send it from memory
		buf, err := os.Open(dst.Name())
		if err != nil {
			log.Fatal(err)
		}
		defer buf.Close()

		return ImageRequestHandler(c, buf)
	})
	e.Logger.Fatal(e.Start(":1324"))
}
