package downloader

import (
	
	

	

	
	
	
)

const maxRetryAttempts = 20

func ( string,  int,  error) error {
	return errors.Wrapf(, "%s: retry limit reached (%d)", , )
}

func ( error) bool {
	return errors.Is(, exchange.ErrKeyFingerprintNotFound)
}

func ( error) bool {
	// Token invalidation requires fetching fresh redirect/token window from
	// master DC.
	return tgerr.Is(
		,
		"FILE_TOKEN_INVALID",
		"REQUEST_TOKEN_INVALID",
	)
}

func ( context.Context,  error) bool {
	if  == nil {
		return false
	}
	if .Err() != nil {
		return false
	}
	if tgerr.Is(, tg.ErrTimeout) || errors.Is(, context.DeadlineExceeded) {
		return true
	}

	var  net.Error
	return errors.As(, &) && .Timeout()
}

func [ any](
	 context.Context,
	 string,
	 func( int,  error),
	 func() (, error),
) ( ,  error) {
	var  
	 := 0
	 := 0
	for {
		if  := .Err();  != nil {
			return , 
		}

		,  := ()
		if ,  := tgerr.FloodWait(, );  != nil {
			if  {
				// FloodWait helper already slept required amount.
				if  := .Err();  != nil {
					return , 
				}
				++
				if  != nil {
					(, )
				}
				continue
			}
			if isRetryableTimeout(, ) {
				// Timeout can happen on unstable proxy links; retry with bounded
				// attempts to avoid infinite tight loops.
				++
				if  >= maxRetryAttempts {
					return , retryLimitErr(, , )
				}
				++
				if  != nil {
					(, )
				}
				continue
			}
			return , 
		}

		return , nil
	}
}