package telegram

import (
	
	
	

	
	
	

	
	
	
)

// API returns *tg.Client for calling raw MTProto methods.
func ( *Client) () *tg.Client {
	return .tg
}

// Invoke invokes raw MTProto RPC method. It sends input and decodes result
// into output.
func ( *Client) ( context.Context,  bin.Encoder,  bin.Decoder) error {
	if .tracer != nil {
		 := "Invoke"
		var  []attribute.KeyValue
		if ,  := .(interface{ () uint32 });  {
			 := .()
			 = append(,
				attribute.Int64("tg.method.id_int", int64()),
				attribute.String("tg.method.id", fmt.Sprintf("%x", )),
			)
			 := .opts.Types.Get()
			if  == "" {
				 = fmt.Sprintf("0x%x", )
			} else {
				 = append(, attribute.String("tg.method.name", ))
			}
			 = fmt.Sprintf("Invoke: %s", )
		}
		,  := .tracer.Start(, ,
			trace.WithAttributes(...),
			trace.WithSpanKind(trace.SpanKindClient),
		)
		 = 
		defer .End()
	}

	return .invoker.Invoke(, , )
}

// invokeDirect directly invokes RPC method, automatically handling datacenter redirects.
func ( *Client) ( context.Context,  bin.Encoder,  bin.Decoder) error {
	if  := .invokeConn(, , );  != nil {
		// Handling datacenter migration request.
		if ,  := tgerr.As();  && strings.HasSuffix(.Type, "_MIGRATE") {
			 := .Argument
			 := .log.With(
				zap.String("error_type", .Type),
				zap.Int("target_dc", ),
			)
			// If migration error is FILE_MIGRATE or STATS_MIGRATE, then the method
			// called by authorized client, so we should try to transfer auth to new DC
			// and create new connection.
			if .IsOneOf("FILE_MIGRATE", "STATS_MIGRATE") {
				.Debug("Invoking on target DC")
				return .invokeSub(, , , )
			}

			// Otherwise we should change primary DC.
			.Info("Migrating to target DC")
			return .invokeMigrate(, , , )
		}

		return 
	}

	return nil
}

// invokeConn directly invokes RPC call on primary connection without any
// additional handling.
func ( *Client) ( context.Context,  bin.Encoder,  bin.Decoder) error {
	.connMux.Lock()
	 := .conn
	.connMux.Unlock()

	return .Invoke(, , )
}