package relaysvc

import (
	
	

	
	
	
	
	relayv2 
)

type RelayManager struct {
	host host.Host

	mutex sync.Mutex
	relay *relayv2.Relay
	opts  []relayv2.Option

	refCount  sync.WaitGroup
	ctxCancel context.CancelFunc
}

func ( host.Host,  ...relayv2.Option) *RelayManager {
	,  := context.WithCancel(context.Background())
	 := &RelayManager{
		host:      ,
		opts:      ,
		ctxCancel: ,
	}
	.refCount.Add(1)
	go .background()
	return 
}

func ( *RelayManager) ( context.Context) {
	defer .refCount.Done()
	defer func() {
		.mutex.Lock()
		if .relay != nil {
			.relay.Close()
		}
		.mutex.Unlock()
	}()

	,  := .host.EventBus().Subscribe(new(event.EvtLocalReachabilityChanged), eventbus.Name("relaysvc"))
	defer .Close()

	for {
		select {
		case <-.Done():
			return
		case ,  := <-.Out():
			if ! {
				return
			}
			if  := .reachabilityChanged(.(event.EvtLocalReachabilityChanged).Reachability);  != nil {
				return
			}
		}
	}
}

func ( *RelayManager) ( network.Reachability) error {
	switch  {
	case network.ReachabilityPublic:
		.mutex.Lock()
		defer .mutex.Unlock()
		// This could happen if two consecutive EvtLocalReachabilityChanged report the same reachability.
		// This shouldn't happen, but it's safer to double-check.
		if .relay != nil {
			return nil
		}
		,  := relayv2.New(.host, .opts...)
		if  != nil {
			return 
		}
		.relay = 
	default:
		.mutex.Lock()
		defer .mutex.Unlock()
		if .relay != nil {
			 := .relay.Close()
			.relay = nil
			return 
		}
	}
	return nil
}

func ( *RelayManager) () error {
	.ctxCancel()
	.refCount.Wait()
	return nil
}