package helper

import (
	"context"
	"errors"
	"fmt"
	"io"
	"net"
	"net/http"
	"strings"
	"time"

	"code.gitea.io/sdk/gitea"
	"github.com/spf13/cobra"
)

var errNoReleasesFound = errors.New("attempt to fetch contracts archive from the offitial repository failed: no releases found")

func downloadContracts(cmd *cobra.Command, url string) (io.ReadCloser, error) {
	cmd.Printf("Downloading contracts archive from '%s'\n", url)

	// HTTP client with connect timeout
	client := http.Client{
		Transport: &http.Transport{
			DialContext: (&net.Dialer{
				Timeout: 10 * time.Second,
			}).DialContext,
		},
	}

	ctx, cancel := context.WithTimeout(cmd.Context(), 60*time.Second)
	defer cancel()

	req, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil)
	if err != nil {
		return nil, fmt.Errorf("can't create request: %w", err)
	}

	resp, err := client.Do(req)
	if err != nil {
		return nil, fmt.Errorf("can't fetch contracts archive: %w", err)
	}
	return resp.Body, nil
}

func downloadContractsFromRepository(cmd *cobra.Command) (io.ReadCloser, error) {
	client, err := gitea.NewClient("https://git.frostfs.info")
	if err != nil {
		return nil, fmt.Errorf("can't initialize repository client: %w", err)
	}

	releases, _, err := client.ListReleases("TrueCloudLab", "frostfs-contract", gitea.ListReleasesOptions{})
	if err != nil {
		return nil, fmt.Errorf("can't fetch release information: %w", err)
	}

	var latestRelease *gitea.Release
	for _, r := range releases {
		if !r.IsDraft && !r.IsPrerelease {
			latestRelease = r
			break
		}
	}

	if latestRelease == nil {
		return nil, errNoReleasesFound
	}

	cmd.Printf("Found release %s (%s)\n", latestRelease.TagName, latestRelease.Title)

	var url string
	for _, a := range latestRelease.Attachments {
		if strings.HasPrefix(a.Name, "frostfs-contract") {
			url = a.DownloadURL
			break
		}
	}
	if url == "" {
		return nil, errors.New("can't find contracts archive in the latest release")
	}

	return downloadContracts(cmd, url)
}