package transport

import (
	"encoding/json"
	"fmt"
	"os"
)

// Kind identifies which messaging fabric a bot runs on.
type Kind string

const (
	// KindMatrix is the proven Matrix (mautrix) path — the default, so master
	// stays on the battle-tested transport.
	KindMatrix Kind = "matrix"
	// KindUnibus routes the bot over the unibus message bus.
	KindUnibus Kind = "unibus"
)

// Select chooses a bot's transport. unibus is used only when the global feature
// flag is enabled AND the bot has opted in; otherwise Matrix. This is the
// branch-by-abstraction toggle: with the flag on, bots migrate to unibus one at
// a time by opting in, while every other bot keeps speaking Matrix unchanged.
func Select(flagEnabled, botOptIn bool) Kind {
	if flagEnabled && botOptIn {
		return KindUnibus
	}
	return KindMatrix
}

// flagsFile mirrors dev/feature_flags.json (see .claude rule feature_flags.md).
type flagsFile struct {
	Flags map[string]struct {
		Enabled     bool   `json:"enabled"`
		Issue       string `json:"issue"`
		Description string `json:"description"`
	} `json:"flags"`
}

// FlagEnabled reports whether the named feature flag is enabled in the given
// dev/feature_flags.json file. A missing file or missing flag reads as false
// (fail-safe: default to the Matrix path), not an error — only malformed JSON
// surfaces an error.
func FlagEnabled(path, name string) (bool, error) {
	data, err := os.ReadFile(path)
	if err != nil {
		if os.IsNotExist(err) {
			return false, nil
		}
		return false, fmt.Errorf("transport: read flags %q: %w", path, err)
	}
	var f flagsFile
	if err := json.Unmarshal(data, &f); err != nil {
		return false, fmt.Errorf("transport: parse flags %q: %w", path, err)
	}
	return f.Flags[name].Enabled, nil
}
