// Copyright 2026 Moko Consulting <hello@mokoconsulting.tech>
// SPDX-License-Identifier: GPL-3.0-or-later

package repo

import (
	updateserver_model "code.mokoconsulting.tech/MokoConsulting/MokoGitea/models/updateserver"
	"code.mokoconsulting.tech/MokoConsulting/MokoGitea/modules/log"
	"code.mokoconsulting.tech/MokoConsulting/MokoGitea/services/context"
)

// CheckDownloadGating validates license key for release downloads when gating is enabled.
// Returns true if the download should proceed, false if it should be blocked.
// The tagName parameter is used for prerelease-only gating (empty = always check).
func CheckDownloadGating(ctx *context.Context, tagName string) bool {
	if ctx.Repo == nil || ctx.Repo.Repository == nil {
		return true
	}

	repo := ctx.Repo.Repository

	// Check effective config (repo override → org default).
	cfg := updateserver_model.GetEffectiveConfig(ctx, repo.OwnerID, repo.ID)
	if cfg == nil || !cfg.LicensingEnabled {
		return true // licensing not enabled — allow all downloads
	}

	gating := cfg.DownloadGating
	if gating == "" || gating == "none" {
		return true // no download gating configured
	}

	// Signed-in users with repo access bypass download gating.
	// The gate is for anonymous/external clients (Joomla update checker).
	if ctx.IsSigned && ctx.Repo.Permission.HasAnyUnitAccess() {
		return true
	}

	// For prerelease-only gating, check if this is a prerelease tag.
	if gating == "prerelease" && tagName != "" {
		streams := updateserver_model.GetEffectiveStreams(ctx, repo.OwnerID, repo.ID)
		matched := updateserver_model.MatchStreamFromTag(tagName, false, streams)
		if matched == "stable" {
			return true // stable releases are public
		}
	}

	// Gating is active — check for a license key in query params.
	rawKey := ctx.FormString("key")
	if rawKey == "" {
		rawKey = ctx.FormString("download_key")
	}
	if rawKey == "" {
		rawKey = ctx.FormString("dlid")
	}

	if rawKey == "" {
		log.Debug("Download gating: key required but not provided for %s/%s", repo.OwnerName, repo.Name)
		return false
	}

	domain := ctx.FormString("domain")
	key, _, err := updateserver_model.ValidateLicenseKeyForRepo(ctx, rawKey, domain, repo.ID)
	if err != nil {
		log.Debug("Download gating: key validation failed: %v", err)
		return false
	}

	// Record heartbeat on successful download validation.
	_ = updateserver_model.TouchHeartbeat(ctx, key.ID)
	return true
}

// GetSupportURL returns the configured support URL for a repo, or empty string.
func GetSupportURL(ctx *context.Context) string {
	if ctx.Repo == nil || ctx.Repo.Repository == nil {
		return ""
	}
	cfg := updateserver_model.GetEffectiveConfig(ctx, ctx.Repo.Repository.OwnerID, ctx.Repo.Repository.ID)
	if cfg != nil && cfg.SupportURL != "" {
		return cfg.SupportURL
	}
	return ""
}
