package utils

import (
	"context"
	"fmt"
	"io"
	"net/http"
	"time"
)

type HttpClient struct {
	*http.Client
}

func NewDefaultHttpClient() HttpClient {
	return HttpClient{
		Client: &http.Client{},
	}
}

func (c HttpClient) Send(req *http.Request) (*http.Response, error) {
	resp, err := c.Do(req)
	if err != nil {
		return nil, err
	}

	if resp.StatusCode < 200 || resp.StatusCode >= 300 {
		content, err := io.ReadAll(resp.Body)
		if err != nil {
			return nil, err
		}

		return nil, fmt.Errorf("request failed: %d , %s", resp.StatusCode, string(content))
	}

	return resp, err
}

func TimePointer(t time.Time) *time.Time {
	return &t
}

func Await(
	ctx context.Context,
	timeout, interval time.Duration,
	f func() (bool, error),
) error {
	ctx, cancel := context.WithTimeout(ctx, timeout)
	defer cancel()

	times := 0
	for {
		select {
		case <-ctx.Done():
			return fmt.Errorf("wait timeout after %d times", times)
		default:
			times++
			if ok, err := f(); err == nil && ok {
				return nil
			} else if err != nil {
				return err
			}
		}

		time.Sleep(interval)
	}
}
