package telegram

import (
	

	
	

	
	
	
	
	
	
	
)

// CloseInvoker is a closeable tg.Invoker.
type CloseInvoker interface {
	tg.Invoker
	Close() error
}

func ( *Client) ( int,  int64,  func() pool.Conn) (*pool.DC, error) {
	select {
	case <-.ctx.Done():
		return nil, errors.Wrap(.ctx.Err(), "client already closed")
	default:
	}

	 := pool.NewDC(.ctx, , , pool.DCOptions{
		Logger:             .log.Named("pool").With(zap.Int("dc_id", )),
		MaxOpenConnections: ,
	})

	return , nil
}

// Pool creates new multi-connection invoker to current DC.
func ( *Client) ( int64) (CloseInvoker, error) {
	if  < 0 {
		return nil, errors.Errorf("invalid max value %d", )
	}

	 := .session.Load()
	return .createPool(.DC, , func() pool.Conn {
		 := .connsCounter.Inc()
		return .createConn(, manager.ConnModeData, nil)
	})
}

func ( *Client) ( context.Context,  int,  int64,  mtproto.Dialer) (*pool.DC, error) {
	if  < 0 {
		return nil, errors.Errorf("invalid max value %d", )
	}

	 := dcs.FindDCs(.cfg.Load().DCOptions, , false)
	if len() < 1 {
		return nil, errors.Errorf("unknown DC %d", )
	}
	.log.Debug("Creating pool",
		zap.Int("dc_id", ),
		zap.Int64("max", ),
		zap.Int("candidates", len()),
	)

	 := .opts
	,  := .createPool(, , func() pool.Conn {
		 := .connsCounter.Inc()

		.sessionsMux.Lock()
		,  := .sessions[]
		if ! {
			 = pool.NewSyncSession(pool.Session{})
			.sessions[] = 
		}
		.sessionsMux.Unlock()

		,  := .Options()
		.Logger = .log.Named("conn").With(
			zap.Int64("conn_id", ),
			zap.Int("dc_id", ),
		)
		return .create(
			, manager.ConnModeData, .appID,
			, manager.ConnOptions{
				DC:      ,
				Device:  .device,
				Handler: .asHandler(),
			},
		)
	})
	if  != nil {
		return nil, errors.Wrap(, "create pool")
	}

	_,  = .transfer(, tg.NewClient(), )
	if  != nil {
		// Ignore case then we are not authorized.
		if auth.IsUnauthorized() {
			return , nil
		}

		// Kill pool if we got error.
		_ = .Close()
		return nil, errors.Wrap(, "transfer")
	}

	return , nil
}

// DC creates new multi-connection invoker to given DC.
func ( *Client) ( context.Context,  int,  int64) (CloseInvoker, error) {
	return .dc(, , , .primaryDC())
}

// MediaOnly creates new multi-connection invoker to given DC ID.
// It connects to MediaOnly DCs.
func ( *Client) ( context.Context,  int,  int64) (CloseInvoker, error) {
	return .dc(, , , func( context.Context) (transport.Conn, error) {
		return .resolver.MediaOnly(, , .dcList())
	})
}