package auth

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

	v4 "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/auth/signer/v4"
	"github.com/aws/aws-sdk-go/aws/credentials"
	"github.com/aws/aws-sdk-go/private/protocol/rest"
)

type RequestData struct {
	Method   string
	Endpoint string
	Bucket   string
	Object   string
}

type PresignData struct {
	Service  string
	Region   string
	Lifetime time.Duration
	SignTime time.Time
}

// PresignRequest forms pre-signed request to access objects without aws credentials.
func PresignRequest(creds *credentials.Credentials, reqData RequestData, presignData PresignData) (*http.Request, error) {
	urlStr := fmt.Sprintf("%s/%s/%s", reqData.Endpoint, rest.EscapePath(reqData.Bucket, false), rest.EscapePath(reqData.Object, false))
	req, err := http.NewRequest(strings.ToUpper(reqData.Method), urlStr, nil)
	if err != nil {
		return nil, fmt.Errorf("failed to create new request: %w", err)
	}

	req.Header.Set(AmzDate, presignData.SignTime.Format("20060102T150405Z"))
	req.Header.Set(ContentTypeHdr, "text/plain")

	signer := v4.NewSigner(creds)
	signer.DisableURIPathEscaping = true

	if _, err = signer.Presign(req, nil, presignData.Service, presignData.Region, presignData.Lifetime, presignData.SignTime); err != nil {
		return nil, fmt.Errorf("presign: %w", err)
	}

	return req, nil
}