package aliyun

import (
	"context"
	"time"

	teautils "github.com/alibabacloud-go/tea-utils/v2/service"
)

// RuntimeOptions applies the same connect and read timeout to an Alicloud SDK call.
func RuntimeOptions(timeout time.Duration) *teautils.RuntimeOptions {
	timeoutMillis := int(timeout / time.Millisecond)
	return (&teautils.RuntimeOptions{}).
		SetConnectTimeout(timeoutMillis).
		SetReadTimeout(timeoutMillis)
}

// CallWithContext makes an Alicloud SDK call cancelable even when the generated
// client method does not accept a context.
func CallWithContext[T any](ctx context.Context, call func() (T, error)) (T, error) {
	type result struct {
		value T
		err   error
	}
	resultCh := make(chan result, 1)
	go func() {
		value, err := call()
		resultCh <- result{value: value, err: err}
	}()

	select {
	case <-ctx.Done():
		var zero T
		return zero, ctx.Err()
	case callResult := <-resultCh:
		return callResult.value, callResult.err
	}
}
