// Package tool 异步任务解析器
package tool

// ExampleUsage 使用示例
// func ExampleUsage() (int, error) {
// 	f := func() (int, error) {
// 		if true {
// 			return 0, errors.New("fail")
// 		}
// 		return 1, nil
// 	}

// 	resolver := NewResolver(f)

// 	defer resolver.Clear()

// 	// 其他逻辑

// 	// 获取解析结果
// 	res, err := resolver.Get()
// 	if err != nil {
// 		return 0, errors.New("获取解析结果失败")
// 	}

// 	return res, nil
// }

// Resolver 异步任务解析器
type Resolver[T any] struct {
	ResultCh chan T     // 这个存的是结果
	ErrorCh  chan error // 这个存的是错误
}

// Get 获取解析结果
func (r Resolver[T]) Get() (T, error) {
	select {
	case res := <-r.ResultCh:
		return res, nil
	case err := <-r.ErrorCh:
		return *new(T), err
	}
}

// Clear 清除解析器的结果
func (r Resolver[T]) Clear() {
	_, _ = r.Get()
}

// CloseAll 关闭所有 chan
func (r Resolver[T]) CloseAll() {
	close(r.ResultCh)
	close(r.ErrorCh)
}

// NewResolver 创建异步任务解析器
func NewResolver[T any](f func() (T, error)) Resolver[T] {
	resolver := Resolver[T]{
		ResultCh: make(chan T),
		ErrorCh:  make(chan error),
	}

	go func() {
		defer resolver.CloseAll()

		result, err := f()
		if err != nil {
			resolver.ErrorCh <- err
			return
		}

		resolver.ResultCh <- result
	}()

	return resolver
}

// NewBufResolver 创建异步任务解析器
func NewBufResolver[T any](f func() (T, error)) Resolver[T] {
	resolver := Resolver[T]{
		ResultCh: make(chan T, 1),
		ErrorCh:  make(chan error, 1),
	}

	go func() {
		defer resolver.CloseAll()

		result, err := f()
		if err != nil {
			resolver.ErrorCh <- err
			return
		}

		resolver.ResultCh <- result
	}()

	return resolver
}
