package server

import (
	
	
	
	
	

	
)

// SamplingHandler defines the interface for handling sampling requests from servers.
type SamplingHandler interface {
	CreateMessage(ctx context.Context, request mcp.CreateMessageRequest) (*mcp.CreateMessageResult, error)
}

// ElicitationHandler defines the interface for handling elicitation requests from servers.
type ElicitationHandler interface {
	Elicit(ctx context.Context, request mcp.ElicitationRequest) (*mcp.ElicitationResult, error)
}

// RootsHandler defines the interface for handling roots list requests from servers.
type RootsHandler interface {
	ListRoots(ctx context.Context, request mcp.ListRootsRequest) (*mcp.ListRootsResult, error)
}

type InProcessSession struct {
	sessionID          string
	notifications      chan mcp.JSONRPCNotification
	initialized        atomic.Bool
	loggingLevel       atomic.Value
	clientInfo         atomic.Value
	clientCapabilities atomic.Value
	samplingHandler    SamplingHandler
	elicitationHandler ElicitationHandler
	rootsHandler       RootsHandler
	mu                 sync.RWMutex
}

func ( string,  SamplingHandler) *InProcessSession {
	return &InProcessSession{
		sessionID:       ,
		notifications:   make(chan mcp.JSONRPCNotification, 100),
		samplingHandler: ,
	}
}

func ( string,  SamplingHandler,  ElicitationHandler,  RootsHandler) *InProcessSession {
	return &InProcessSession{
		sessionID:          ,
		notifications:      make(chan mcp.JSONRPCNotification, 100),
		samplingHandler:    ,
		elicitationHandler: ,
		rootsHandler:       ,
	}
}

func ( *InProcessSession) () string {
	return .sessionID
}

func ( *InProcessSession) () chan<- mcp.JSONRPCNotification {
	return .notifications
}

func ( *InProcessSession) () {
	.loggingLevel.Store(mcp.LoggingLevelError)
	.initialized.Store(true)
}

func ( *InProcessSession) () bool {
	return .initialized.Load()
}

func ( *InProcessSession) () mcp.Implementation {
	if  := .clientInfo.Load();  != nil {
		if ,  := .(mcp.Implementation);  {
			return 
		}
	}
	return mcp.Implementation{}
}

func ( *InProcessSession) ( mcp.Implementation) {
	.clientInfo.Store()
}

func ( *InProcessSession) () mcp.ClientCapabilities {
	if  := .clientCapabilities.Load();  != nil {
		if ,  := .(mcp.ClientCapabilities);  {
			return 
		}
	}
	return mcp.ClientCapabilities{}
}

func ( *InProcessSession) ( mcp.ClientCapabilities) {
	.clientCapabilities.Store()
}

func ( *InProcessSession) ( mcp.LoggingLevel) {
	.loggingLevel.Store()
}

func ( *InProcessSession) () mcp.LoggingLevel {
	 := .loggingLevel.Load()
	if  == nil {
		return mcp.LoggingLevelError
	}
	return .(mcp.LoggingLevel)
}

func ( *InProcessSession) ( context.Context,  mcp.CreateMessageRequest) (*mcp.CreateMessageResult, error) {
	.mu.RLock()
	 := .samplingHandler
	.mu.RUnlock()

	if  == nil {
		return nil, fmt.Errorf("no sampling handler available")
	}

	return .CreateMessage(, )
}

func ( *InProcessSession) ( context.Context,  mcp.ElicitationRequest) (*mcp.ElicitationResult, error) {
	.mu.RLock()
	 := .elicitationHandler
	.mu.RUnlock()

	if  == nil {
		return nil, fmt.Errorf("no elicitation handler available")
	}

	return .Elicit(, )
}

// ListRoots sends a list roots request to the client and waits for the response.
// Returns an error if no roots handler is available.
func ( *InProcessSession) ( context.Context,  mcp.ListRootsRequest) (*mcp.ListRootsResult, error) {
	.mu.RLock()
	 := .rootsHandler
	.mu.RUnlock()

	if  == nil {
		return nil, fmt.Errorf("no roots handler available")
	}

	return .ListRoots(, )
}

// GenerateInProcessSessionID generates a unique session ID for inprocess clients
func () string {
	return fmt.Sprintf("inprocess-%d", time.Now().UnixNano())
}

// Ensure interface compliance
var (
	_ ClientSession          = (*InProcessSession)(nil)
	_ SessionWithLogging     = (*InProcessSession)(nil)
	_ SessionWithClientInfo  = (*InProcessSession)(nil)
	_ SessionWithSampling    = (*InProcessSession)(nil)
	_ SessionWithElicitation = (*InProcessSession)(nil)
	_ SessionWithRoots       = (*InProcessSession)(nil)
)