//go:build e2e
// +build e2e

package utils

import (
	"net/http"
	"strings"
	"time"
)

type StressResponse struct {
	Index        int
	Res          *http.Response
	Err          error
	ResponseTime int64
	StartTime    time.Time
}

type StressRequestParam struct {
	Api    string
	Body   []byte
	Method string
}

type Stress struct {
	ApiConcurrency map[string]int   `yaml:"apiConcurrency,omitempty"`
	ApiTimeOut     map[string]int64 `yaml:"apiTimeOut,omitempty"`
}

func GetStressConfig() Stress {
	return config.Stress
}

func StressRequest(cases []StressRequestParam, concurrencyLimit int) []StressResponse {

	semaphoreChan := make(chan struct{}, concurrencyLimit)
	resultsChan := make(chan *StressResponse)

	defer func() {
		close(semaphoreChan)
		close(resultsChan)
	}()
	//fmt.Println(string(request.Body))
	for i, request := range cases {
		//fmt.Println(string(request.Body))
		go func(i int, req StressRequestParam) {
			semaphoreChan <- struct{}{}

			var r *http.Request
			if req.Method == "GET" {
				r, _ = http.NewRequest("GET", req.Api, nil)
			} else {
				r, _ = http.NewRequest(req.Method, req.Api, strings.NewReader(string(req.Body)))
			}
			WithHeader(r)

			startTime := time.Now()
			//fmt.Println("create start time:", startTime.Format("2006-01-02 15:04:05"), i)
			resp, err := http.DefaultClient.Do(r)
			if err != nil {
				panic(err)
			}
			defer resp.Body.Close()
			responseTime := time.Since(startTime).Milliseconds()

			result := StressResponse{i, resp, err, responseTime, startTime}
			resultsChan <- &result
			<-semaphoreChan
		}(i, request)
	}

	var results []StressResponse

	for {
		result := <-resultsChan
		results = append(results, *result)
		if len(results) == len(cases) {
			break
		}
	}

	return results
}
