package checker

import (
	"fmt"
	"github.com/hashicorp/go-multierror"
	"sync"
)

type Result struct {
	Name   string
	Region string
	Err    error
}

func (c *Checker) GetNotUnlockList() (map[string][]string, error) {
	rs := make(chan *Result)
	done := make(chan struct{})
	var fails = make(map[string][]string)
	var errs error
	temp := make(map[string]struct{})
	go func() {
		wg := sync.WaitGroup{}
		for _, region := range c.Regions {
			for _, n := range c.MediaList[region] {
				if _, e := temp[n]; e {
					continue
				}
				temp[n] = struct{}{}
				n := n
				region := region
				wg.Add(1)
				go func() {
					defer wg.Done()
					rsp := mediaList[n](c.client)
					if c.CheckRegion {
						if rsp.Region != region && rsp.Region != "" {
							rs <- &Result{
								Name:   n,
								Region: region,
								Err:    rsp.Err,
							}
							return
						}
					}
					if !rsp.Success {
						rs <- &Result{
							Name:   n,
							Region: region,
							Err:    rsp.Err,
						}
						return
					}
					rs <- nil
				}()
			}
		}
		wg.Wait()
		close(done)
	}()
	for {
		select {
		case <-done:
			return fails, errs
		case n := <-rs:
			if n != nil {
				if n.Err != nil {
					errs = multierror.Append(errs, fmt.Errorf("%s error: %s", n.Name, n.Err))
					continue
				}
				if fail, ok := fails[n.Region]; ok {
					fails[n.Region] = append(fail, n.Name)
				} else {
					fails[n.Region] = []string{
						n.Name,
					}
				}
			}
		}
	}
}
