package main

import (
	"context"
	"fmt"
	"io"
  "time"
  "strings"
  "strconv"

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

type responseEntry struct {
  index int
  value string
  err   error
}

const numberOfElements = 10

func main() {
	fsthttp.ServeFunc(func(ctx context.Context, w fsthttp.ResponseWriter, r *fsthttp.Request) {
    startTime := time.Now()
    previousResponseFinishedTime := startTime

    ch := make(chan responseEntry)

    for i := 0; i < numberOfElements; i++ {
      go func(index int) {
        req, err := fsthttp.NewRequest("GET", fmt.Sprintf("https://http-me.glitch.me/body=response-%d", index+1), nil)
        if err != nil {
          ch <- responseEntry{index:index, err: err}
          return
        }

        resp, err := req.Send(ctx, "origin_0")
        if err != nil {
          ch <- responseEntry{index:index, err: err}
          return
        }

        var str string
        if resp.StatusCode != 200 {
          str = "Invalid response"
        } else {
          buf := new(strings.Builder)
          _, err = io.Copy(buf, resp.Body)
          if err != nil {
            ch <- responseEntry{index:index, err: err}
            return
          }
          str = buf.String()
        }

        endTime := time.Now()
        executionTime := endTime.Sub(startTime)
        fmt.Printf(
          "# %d %s Since start: %d ms Since previous response %d ms",
          index + 1,
          str,
          int64(executionTime / time.Millisecond),
          int64(endTime.Sub(previousResponseFinishedTime) / time.Millisecond),
        )

        previousResponseFinishedTime = endTime

        ch <- responseEntry{index:index, value:str}
      }(i)
    }

    values := make([]string, numberOfElements)
    for i := 1; i <= numberOfElements; i++ {
      entry := <-ch;
      if entry.err != nil {
  			w.WriteHeader(500)
			  fmt.Fprintln(w, entry.err.Error())
			  return
      }
      
      values[entry.index] = entry.value
    }

    endTime := time.Now()
    executionTime := endTime.Sub(startTime)
    fmt.Printf("Execution time: %d ms", int64(executionTime / time.Millisecond))

    h := fsthttp.NewHeader()
    h.Add("Content-Type", "text/plain")
    h.Add("x-exec-time", strconv.FormatInt(int64(executionTime / time.Millisecond), 10))

    resp := fsthttp.Response{
      Header:     h,
      StatusCode: fsthttp.StatusOK,
      Body:       io.NopCloser(strings.NewReader(strings.Join(values, ","))),
    }

    w.Header().Reset(resp.Header)
    w.WriteHeader(resp.StatusCode)
    io.Copy(w, resp.Body)
	})
}