package pulls

import (
	"log/slog"
	"time"

	"tangled.org/core/appview/config"
	"tangled.org/core/appview/db"
	pulls_indexer "tangled.org/core/appview/indexer/pulls"
	"tangled.org/core/appview/knotacl"
	"tangled.org/core/appview/mentions"
	"tangled.org/core/appview/models"
	"tangled.org/core/appview/notify"
	"tangled.org/core/appview/oauth"
	"tangled.org/core/appview/pages"
	"tangled.org/core/appview/reporesolver"
	knotmirror "tangled.org/core/gitmirror/proto/gen"
	"tangled.org/core/idresolver"
	"tangled.org/core/ogre"
	"tangled.org/core/types"

	"github.com/bluesky-social/indigo/util"
	indigoxrpc "github.com/bluesky-social/indigo/xrpc"
	"github.com/hashicorp/golang-lru/v2/expirable"
)

const ApplicationGzip = "application/gzip"

const (
	diffCacheSize = 128
	diffCacheTTL  = 15 * time.Minute
)

type Pulls struct {
	oauth            *oauth.OAuth
	repoResolver     *reporesolver.RepoResolver
	pages            *pages.Pages
	idResolver       *idresolver.Resolver
	mentionsResolver *mentions.Resolver
	db               *db.DB
	config           *config.Config
	notifier         notify.Notifier
	acl              *knotacl.Service
	logger           *slog.Logger
	indexer          *pulls_indexer.Indexer
	ogreClient       *ogre.Client
	diffCache        *expirable.LRU[string, types.DiffRenderer]
	gitmirror        knotmirror.GitMirrorServiceClient

	knotMirrorXRPC *indigoxrpc.Client
}

func New(
	oauth *oauth.OAuth,
	repoResolver *reporesolver.RepoResolver,
	pages *pages.Pages,
	resolver *idresolver.Resolver,
	mentionsResolver *mentions.Resolver,
	db *db.DB,
	config *config.Config,
	notifier notify.Notifier,
	acl *knotacl.Service,
	indexer *pulls_indexer.Indexer,
	logger *slog.Logger,
	gitmirror knotmirror.GitMirrorServiceClient,
) *Pulls {
	return &Pulls{
		oauth:            oauth,
		repoResolver:     repoResolver,
		pages:            pages,
		idResolver:       resolver,
		mentionsResolver: mentionsResolver,
		db:               db,
		config:           config,
		notifier:         notifier,
		acl:              acl,
		logger:           logger,
		indexer:          indexer,
		ogreClient:       ogre.NewClient(config.Ogre.Host),
		diffCache:        expirable.NewLRU[string, types.DiffRenderer](diffCacheSize, nil, diffCacheTTL),
		gitmirror:        gitmirror,

		knotMirrorXRPC: &indigoxrpc.Client{
			Host:   config.KnotMirror.Url,
			Client: util.RobustHTTPClient(),
		},
	}
}

func ptrPullState(s models.PullState) *models.PullState { return &s }
