package actor

import (
	"net/http"

	"github.com/gogo/protobuf/proto"
)

type MutationResult[V any] struct {
	Result    V             `json:"result"`
	Mutations []ApplyResult `json:"mutations,omitempty"`
}

type GrainPool[V any] interface {
	Apply(id uint64, mutation ...proto.Message) (*MutationResult[V], error)
	Get(id uint64) (V, error)
	OwnerHost(id uint64) (Host, bool)
	Hostname() string
	TakeOwnership(id uint64)
	HandleOwnershipChange(host string, ids []uint64) error
	HandleRemoteExpiry(host string, ids []uint64) error
	Negotiate(otherHosts []string)
	GetLocalIds() []uint64
	RemoveHost(host string)
	IsHealthy() bool
	IsKnown(string) bool
	Close()
}

// Host abstracts a remote node capable of proxying cart requests.
type Host interface {
	AnnounceExpiry(ids []uint64)
	Negotiate(otherHosts []string) ([]string, error)
	Name() string
	Proxy(id uint64, w http.ResponseWriter, r *http.Request) (bool, error)
	GetActorIds() []uint64
	Close() error
	Ping() bool
	IsHealthy() bool
	AnnounceOwnership(ownerHost string, ids []uint64)
}
