package main

import (
	"Study/src/study/day7Function/HtmlTools"
	"fmt"
	"log"
)

// 接下来，我们讨论一个有点学术性的例子，考虑这样一个问题：
// 给定一些计算机课程，每个课程都有前置课程，只有完成了前置课程才可以开始当前课程的学习；
// 我们的目标是选择出一组课程，这组课程必须确保按顺序学习时，能全部被完成。每个课程的前置课程如下：

// prereqs记录了每个课程的前置课程
var prereqs = map[string][]string{
	"algorithms":     {"data structures"},
	"linear algebra": {"calculus"},
	"calculus":       {"linear algebra"},
	"compilers": {
		"data structures",
		"formal languages",
		"computer organization",
	},
	"data structures":       {"discrete math"},
	"databases":             {"data structures"},
	"discrete math":         {"intro to programming"},
	"formal languages":      {"discrete math"},
	"networks":              {"operating systems"},
	"operating systems":     {"data structures", "computer organization"},
	"programming languages": {"data structures", "computer organization"},
}

func main() {
	//	for i, course := range topoSort(prereqs) {
	//		fmt.Printf("%d:\t%s\n", i, course)
	//	}
	//fmt.Println(hasCycle(prereqs))
	//topoSort(prereqs)
	//fmt.Printf("%v", len(prereqs["qqq"]))
	//BreadthFirst(crawl, []string{"all"})
}

// BreadthFirst
// calls f() for each item in the worklist.
// Any items returned by f() are added to the worklist.
// f() is called at most once for each item.
//
//		-
//
//	 BreadthFirst 队列中的每节点都调用f()。
//	 f()返回的所有节点都被添加到队列中。
//	 对每个节点最多调用一次f()。
//
//		f		func(item string) []string
//		returns []string
func BreadthFirst(f func(item string) []string, worklist []string) {
	// seen
	seen := make(map[string]bool)
	for len(worklist) > 0 {
		// 复制当前队列
		items := worklist
		// 清空队列
		worklist = nil
		// 遍历复制的当前队列
		for _, item := range items {
			// 判断seen, 防止重复添加到队列
			if !seen[item] {
				seen[item] = true
				// 添加到队列
				worklist = append(worklist, f(item)...)
			}
		}
	}
}

// crawl 此函数返回一个[]string, 内容为url
func crawl(url string) []string {
	fmt.Println(url)
	list, err := HtmlTools.Extract()
	if err != nil {
		log.Print(err)
	}
	return list
}
