// Package plugin defines the Source and Trigger contracts that decouple
// Tinyforge's deployer pipeline from any single deployable shape (image,
// compose, static, ...) or any single redeploy trigger (registry push,
// git push, manual, ...).
//
// A Workload is the unifying user-facing entity. It carries an opaque
// SourceConfig (interpreted by the matching Source) and an opaque
// TriggerConfig (interpreted by the matching Trigger). Both kinds are
// strings; lookup happens through the registries below.
//
// New deployable shapes or trigger types are added by:
//  1. Implementing Source or Trigger in a sub-package.
//  2. Calling Register (Source/Trigger) from that package's init().
//  3. Blank-importing the sub-package from cmd/ to pull the registration in.
//
// No code in this package or in the deployer/api layers needs to change
// when a new kind appears — the registry is the only seam.
package plugin

import (
	"encoding/json"

	"github.com/alexei/tinyforge/internal/dns"
	"github.com/alexei/tinyforge/internal/docker"
	"github.com/alexei/tinyforge/internal/events"
	"github.com/alexei/tinyforge/internal/health"
	"github.com/alexei/tinyforge/internal/notify"
	"github.com/alexei/tinyforge/internal/proxy"
	"github.com/alexei/tinyforge/internal/store"
)

// Deps is the bundle of services every Source or Trigger may need. Passed
// per-call so plugin implementations stay stateless and testable.
type Deps struct {
	Store    *store.Store
	Docker   *docker.Client
	Proxy    proxy.Provider
	DNS      dns.Provider // nil when wildcard DNS is active
	Health   *health.Checker
	Notifier *notify.Notifier
	Events   EventPublisher
	EncKey   [32]byte // pass-through to crypto.Encrypt/Decrypt for config secrets
}

// EventPublisher matches the deployer's existing event-bus surface. Kept as
// a local interface so plugin/ does not pull events transitively into every
// caller.
type EventPublisher interface {
	Publish(evt events.Event)
}

// Workload is the value-shape every plugin consumes. It is constructed by
// the store layer from the workloads row plus its decoded JSON blobs; the
// physical schema can evolve independently of this struct.
type Workload struct {
	ID               string
	Name             string
	GroupID          string // formerly app_id; "" = ungrouped
	ParentWorkloadID string // for stage chains; "" = root

	SourceKind    string          // "image" | "compose" | "static" | ...
	SourceConfig  json.RawMessage // shape determined by SourceKind

	TriggerKind   string          // "registry" | "git" | "manual" | "schedule" | ...
	TriggerConfig json.RawMessage // shape determined by TriggerKind

	PublicFaces []PublicFace // zero or more public routes

	// Notification + webhook security live on the Workload itself rather
	// than on per-kind tables so the rules are consistent across shapes.
	NotificationURL         string
	NotificationSecret      string
	WebhookSecret           string
	WebhookSigningSecret    string
	WebhookRequireSignature bool

	CreatedAt string
	UpdatedAt string
}
