// https://developer.fastly.com/solutions/examples/smoke-test-a-new-origin
package main

import (
	"context"
	"fmt"
	"io"
	"os"
	"sync"

	"github.com/fastly/compute-sdk-go/fsthttp"
)

// BackendTest is the name of our test environment backend.
const BackendTest = "origin_0"

// BackendProd is the name of our production environment backend.
const BackendProd = "origin_1"

func main() {
	fsthttp.ServeFunc(func(ctx context.Context, w fsthttp.ResponseWriter, r *fsthttp.Request) {
		var (
			err      error
			respTest *fsthttp.Response
			respProd *fsthttp.Response
			wg       sync.WaitGroup
		)

		// Expect two concurrent sets of requests to be in-flight.
		wg.Add(2)

		// A request can't call .Send() twice.
		// The incoming request object will be used for the test environment backend request.
		// We clone it for the production environment backend request.
		rc := r.Clone()

		// Send request to test environment backend.
		go func() {
			defer wg.Done()
			var err error // Avoid shadowing parent err variable used by production request.
      
			respTest, err = r.Send(ctx, BackendTest)
			if err != nil {
				fmt.Fprintf(os.Stderr, "test backend: %s\n", err)
			}
		}()

		// Send request to production environment backend.
		go func() {
			defer wg.Done()
			respProd, err = rc.Send(ctx, BackendProd)
		}()

		// Wait for all requests to complete.
		wg.Wait()

		// Check for production error
		if err != nil {
			w.WriteHeader(fsthttp.StatusBadGateway)
			fmt.Fprintln(w, err)
			return
		}

		// Compare responses from test and production backends.
		sameStatus := respTest.StatusCode == respProd.StatusCode
		sameContent := respTest.Header.Get("Content-Length") == respProd.Header.Get("Content-Length")
		if sameStatus && sameContent {
			fmt.Println("Prod and test are the same")
		} else {
			fmt.Println("The production and test environments returned different content")
		}

		// Use the production response.
		w.Header().Reset(respProd.Header)
		w.WriteHeader(respProd.StatusCode)
		io.Copy(w, respProd.Body)
	})
}