package plugin

import (
	"fmt"
	"time"
)

// Deploy strategy values for a source's DeployStrategy config field.
//
//   - "" (empty)      — back-compat default; each source resolves it to its
//     historical behavior (image -> blue-green, others -> recreate). Every
//     pre-existing workload row decodes to this.
//   - StrategyRecreate — stop the old container, then start the new one
//     (a brief downtime window; what dockerfile/static/compose do today).
//   - StrategyBlueGreen — start the new container alongside the old, gate it,
//     swap the proxy route, then reap the old (zero-downtime under NPM).
const (
	StrategyRecreate  = "recreate"
	StrategyBlueGreen = "blue-green"
)

// ValidateStrategy checks a deploy_strategy config value. "" is always valid
// (the back-compat default). StrategyRecreate is always valid. StrategyBlueGreen
// is valid only when the source supports it (allowBlueGreen) — compose passes
// false because a whole-stack blue-green is not implemented. Reserved values
// such as "rolling" are rejected until implemented so a config can't silently
// claim a behavior the deployer won't honor.
func ValidateStrategy(value string, allowBlueGreen bool) error {
	switch value {
	case "", StrategyRecreate:
		return nil
	case StrategyBlueGreen:
		if allowBlueGreen {
			return nil
		}
		return fmt.Errorf("deploy_strategy %q is not supported for this source kind; use \"recreate\"", value)
	default:
		return fmt.Errorf("invalid deploy_strategy %q (valid: \"\", %q, %q)", value, StrategyRecreate, StrategyBlueGreen)
	}
}

// BuildGreenName appends a unique millisecond-hex suffix to a source's
// otherwise-deterministic container name so a new "green" container can run
// alongside the old "blue" during a blue-green cutover. Sources whose names
// are deterministic (dockerfile, static) collide on Docker's per-daemon
// unique-name constraint without this; the suffix lets both coexist until the
// route swaps and blue is reaped. Mirrors the image source's ms-hex scheme.
func BuildGreenName(base string, ts time.Time) string {
	return fmt.Sprintf("%s-%x", base, ts.UnixMilli())
}
