package application

import (
	"context"
	"errors"
	"fmt"
	"io/ioutil"
	"net/http"
	"net/url"
	"strconv"
	"strings"
	"time"
)

type Query struct {
	Width  int
	Height int
	URL    *url.URL
}

func buildQuery(u *url.URL) (q Query, err error) {
	t := strings.Split(u.Path, "/")
	if len(t) < 5 {
		return Query{}, errors.New("need more params")
	}
	q.Width, err = strconv.Atoi(t[2])
	if err != nil {
		return Query{}, errors.New("width must be an integer")
	}
	q.Height, err = strconv.Atoi(t[3])
	if err != nil {
		return Query{}, errors.New("height must be an integer")
	}
	tn := "http://" + strings.Join(t[4:], "/")
	q.URL, err = q.URL.Parse(tn)
	if err != nil {
		return Query{}, errors.New("not valid url")
	}
	return q, nil
}

func (q Query) id() string {
	return strings.ReplaceAll(strconv.Itoa(q.Width)+"/"+strconv.Itoa(q.Height)+q.URL.Path, "/", "_")
}

func (q Query) fromOrigin(ctx context.Context, headers http.Header, timeout time.Duration) ([]byte, *http.Response, error) {
	client := &http.Client{Timeout: timeout}
	req, err := http.NewRequestWithContext(ctx, "GET", "http://"+q.URL.Host+q.URL.Path, nil)
	if err != nil {
		return nil, nil, fmt.Errorf("can't create request:\n %w", err)
	}
	req.Header = headers
	req.Close = true
	res, err := client.Do(req)
	if err != nil {
		return nil, nil, fmt.Errorf("can't do request:\n %w", err)
	}
	body, err := ioutil.ReadAll(res.Body)
	defer res.Body.Close()
	if err != nil {
		return nil, nil, fmt.Errorf("can't read body from response:\n %w", err)
	}
	return body, res, nil
}