package main

import (
	"bytes"
	"context"
	"fmt"
	"io"
	"log"
	"strings"

	"github.com/fastly/compute-sdk-go/fsthttp"
	"github.com/rwcarlsen/goexif/exif"
	"github.com/rwcarlsen/goexif/tiff"
)

// BackendName is the name of our service backend.
const BackendName = "origin_0"

type Printer struct {
	resp fsthttp.Response
}

func (p Printer) Walk(name exif.FieldName, tag *tiff.Tag) error {
	// Remove double quotes around value (if present)
	s := tag.String()
	if len(s) > 0 && s[0] == '"' {
		s = s[1:]
	}
	if len(s) > 0 && s[len(s)-1] == '"' {
		s = s[:len(s)-1]
	}
	// Add the tag as a header
	p.resp.Header.Add("Edge-Exif-"+string(name), s)
	return nil
}

func main() {
	fsthttp.ServeFunc(func(ctx context.Context, w fsthttp.ResponseWriter, r *fsthttp.Request) {
		// Grab the backend response
		resp, err := r.Send(ctx, BackendName)
		if err != nil {
			w.WriteHeader(fsthttp.StatusBadGateway)
			fmt.Fprintln(w, err.Error())
			return
		}

		// Extract exif tags, if this is an image request
		if strings.HasPrefix(resp.Header.Get("Content-Type"), "image/") {
			// read the response body to a variable so that it can be used later
			bodyBytes, _ := io.ReadAll(resp.Body)
			// Reset the body so it can be streamed again
			resp.Body = io.NopCloser(bytes.NewBuffer(bodyBytes))
			// Extract the EXIF data
			metaData, err := exif.Decode(resp.Body)
			if err != nil {
				log.Fatal(err)
			}
			// Loop through the EXIF values
			var p Printer
			p.resp = *resp
			metaData.Walk(p)
			// Reset the body so it can be streamed again
			resp.Body = io.NopCloser(bytes.NewBuffer(bodyBytes))
		}

		// Return the original response
		w.Header().Reset(resp.Header)
		w.WriteHeader(resp.StatusCode)
		io.Copy(w, resp.Body)
	})
}