package main

type Fetcher interface {
	// Fetch returns the body of URL and
	// a slice of URLs found on that page.
	Fetch(url string) (body string, urls []string, err error)
}

// Crawl uses fetcher to recursively crawl
// pages starting with url, to a maximum of depth.
func Crawl(url string, depth int, fetcher Fetcher) ([]string, error) {
	// TODO: Fetch URLs in parallel.
	// TODO: Don't fetch the same URL twice.
	// This implementation doesn't do either:
	if depth <= 0 {
		return nil, nil
	}
	body, urls, err := fetcher.Fetch(url)
	if err != nil {
		return nil, err
	}
	result := []string{body}
	for _, u := range urls {
		if res, err := Crawl(u, depth-1, fetcher); err == nil {
			result = append(result, res...)
		}
	}
	return result, nil
}