// Package node is the core IOP Node service. It implements
// transport.Handler and orchestrates routing → adapter execution.
package node

import (
	"io"
	"os"
	"sync"

	"go.uber.org/zap"

	"iop/apps/node/internal/adapters"
	"iop/apps/node/internal/runtime"
	"iop/apps/node/internal/store"
)

// Node implements transport.Handler and coordinates the full execution pipeline.
type Node struct {
	nodeID           string
	router           runtime.Router
	store            *store.Store
	runs             *runManager
	globalGate       *fifoGate // node-wide concurrency safety guard across all adapters (retained for compatibility; not used for admission)
	adapterGatesMu   sync.Mutex
	adapterGates     map[string]*fifoGate // per adapter-key concurrency safety guard
	out              io.Writer
	logger           *zap.Logger
	currentConfigSet *adapters.ConfigSet
	configSetMu      sync.RWMutex
}

// New creates a Node. It satisfies transport.Handler.
// globalConcurrency is retained as a compatibility argument but is no longer
// used for admission. Node-wide concurrency limits have been removed; per-
// adapter MaxConcurrency from Capabilities is the sole admission gate.
// out receives console debug output; pass os.Stdout for production, io.Discard in tests.
func New(
	nodeID string,
	router runtime.Router,
	st *store.Store,
	globalConcurrency int,
	out io.Writer,
	logger *zap.Logger,
	initialConfigSet *adapters.ConfigSet,
) *Node {
	if out == nil {
		out = os.Stdout
	}
	return &Node{
		nodeID:           nodeID,
		router:           router,
		store:            st,
		runs:             newRunManager(),
		globalGate:       newFifoGate(globalConcurrency),
		adapterGates:     make(map[string]*fifoGate),
		out:              out,
		logger:           logger,
		currentConfigSet: initialConfigSet,
	}
}
