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

package updateserver

import (
	"context"

	"code.mokoconsulting.tech/MokoConsulting/MokoGitea/models/db"
	"code.mokoconsulting.tech/MokoConsulting/MokoGitea/modules/timeutil"
)

func init() {
	db.RegisterModel(new(LicenseKeyUsage))
}

// LicenseKeyUsage tracks update check activity for a license key.
type LicenseKeyUsage struct {
	ID          int64              `xorm:"pk autoincr"`
	KeyID       int64              `xorm:"INDEX NOT NULL"`
	RepoID      int64              `xorm:"INDEX NOT NULL"`
	Domain      string             `xorm:""`            // requesting domain from extra_query
	IPAddress   string             `xorm:""`
	UserAgent   string             `xorm:"TEXT"`
	VersionFrom string             `xorm:""`            // version the client is updating from
	CreatedUnix timeutil.TimeStamp `xorm:"INDEX CREATED"`
}

func (LicenseKeyUsage) TableName() string {
	return "license_key_usage"
}

// RecordUsage inserts a usage tracking entry.
func RecordUsage(ctx context.Context, usage *LicenseKeyUsage) error {
	_, err := db.GetEngine(ctx).Insert(usage)
	return err
}

// GetRecentUsage returns the most recent usage entries for a key.
func GetRecentUsage(ctx context.Context, keyID int64, limit int) ([]*LicenseKeyUsage, error) {
	usages := make([]*LicenseKeyUsage, 0, limit)
	return usages, db.GetEngine(ctx).Where("key_id = ?", keyID).
		OrderBy("created_unix DESC").Limit(limit).Find(&usages)
}

// CountUsageByKey returns the total number of update checks for a key.
func CountUsageByKey(ctx context.Context, keyID int64) (int64, error) {
	return db.GetEngine(ctx).Where("key_id = ?", keyID).Count(new(LicenseKeyUsage))
}

// CountUniqueDomainsByKey returns the number of distinct domains that have used a key.
func CountUniqueDomainsByKey(ctx context.Context, keyID int64) (int64, error) {
	count, err := db.GetEngine(ctx).
		Where("key_id = ? AND domain != ''", keyID).
		Distinct("domain").
		Count(new(LicenseKeyUsage))
	return count, err
}

// IsDomainKnownForKey checks whether a specific domain has already been recorded for a key.
func IsDomainKnownForKey(ctx context.Context, keyID int64, domain string) (bool, error) {
	return db.GetEngine(ctx).
		Where("key_id = ? AND domain = ?", keyID, domain).
		Exist(new(LicenseKeyUsage))
}
