package server

import (
	"context"
	"encoding/json"
	"fmt"
	"log"
	"net/http"
	"strings"
	"time"
)

const latestReleaseURL = "https://api.github.com/repos/sartoopjj/thefeed/releases/latest"

type githubRelease struct {
	TagName string `json:"tag_name"`
}

// startLatestVersionTracker periodically fetches latest GitHub release version
// and stores it in the dedicated version channel.
func startLatestVersionTracker(ctx context.Context, feed *Feed) {
	update := func() {
		v, err := fetchLatestReleaseVersion(ctx)
		if err != nil {
			log.Printf("[version] check latest release failed: %v", err)
			return
		}
		feed.SetLatestVersion(v)
	}

	update()
	ticker := time.NewTicker(6 * time.Hour)
	defer ticker.Stop()
	for {
		select {
		case <-ctx.Done():
			return
		case <-ticker.C:
			update()
		}
	}
}

func fetchLatestReleaseVersion(parent context.Context) (string, error) {
	ctx, cancel := context.WithTimeout(parent, 10*time.Second)
	defer cancel()

	req, err := http.NewRequestWithContext(ctx, http.MethodGet, latestReleaseURL, nil)
	if err != nil {
		return "", err
	}
	req.Header.Set("User-Agent", "thefeed-server")
	req.Header.Set("Accept", "application/vnd.github+json")

	resp, err := http.DefaultClient.Do(req)
	if err != nil {
		return "", err
	}
	defer resp.Body.Close()
	if resp.StatusCode != http.StatusOK {
		return "", fmt.Errorf("latest release status: %s", resp.Status)
	}

	var rel githubRelease
	if err := json.NewDecoder(resp.Body).Decode(&rel); err != nil {
		return "", err
	}
	v := strings.TrimSpace(rel.TagName)
	v = strings.TrimPrefix(v, "v")
	if v == "" {
		return "", fmt.Errorf("empty latest release tag")
	}
	return v, nil
}
