package plugin

import (
	"encoding/json"
	"log/slog"

	"github.com/alexei/tinyforge/internal/store"
)

// WorkloadFromStore converts a persisted store.Workload row into the value
// shape that Source / Trigger plugins consume. It is the single converter
// shared by every caller (api, reconciler, webhook) — previously each kept
// its own byte-identical copy, which drifted (only the api copy logged bad
// PublicFaces JSON; the others swallowed it).
//
// Living in the plugin package is safe: plugin already imports store (Deps
// holds a *store.Store), so this adds no new edge to the dependency graph
// and store does not import plugin.
//
// SourceConfig / TriggerConfig are passed through as raw JSON; the matching
// plugin decodes them with plugin.SourceConfigOf[T] / TriggerConfigOf[T].
// PublicFaces is decoded eagerly because every consumer needs the parsed
// slice (proxy registration, UI, validation); invalid JSON is logged and
// treated as empty rather than failing the conversion.
func WorkloadFromStore(w store.Workload) Workload {
	var faces []PublicFace
	if w.PublicFaces != "" {
		if err := json.Unmarshal([]byte(w.PublicFaces), &faces); err != nil {
			slog.Warn("workload: invalid public_faces JSON, treating as empty",
				"workload", w.ID, "error", err)
			faces = nil
		}
	}
	return Workload{
		ID:                      w.ID,
		Name:                    w.Name,
		GroupID:                 w.AppID,
		ParentWorkloadID:        w.ParentWorkloadID,
		SourceKind:              w.SourceKind,
		SourceConfig:            json.RawMessage(w.SourceConfig),
		TriggerKind:             w.TriggerKind,
		TriggerConfig:           json.RawMessage(w.TriggerConfig),
		PublicFaces:             faces,
		NotificationURL:         w.NotificationURL,
		NotificationSecret:      w.NotificationSecret,
		WebhookSecret:           w.WebhookSecret,
		WebhookSigningSecret:    w.WebhookSigningSecret,
		WebhookRequireSignature: w.WebhookRequireSignature,
		CreatedAt:               w.CreatedAt,
		UpdatedAt:               w.UpdatedAt,
	}
}
