package main

import (
	"fmt"
	"log"
	"regexp"

	"github.com/PuerkitoBio/goquery"
)

type DownloadVersion struct {
	File, Kind, OS, Arch, Size, Digest string
	DownloadURL                        string
}

func matchesFilter(v *DownloadVersion) bool {
	if !(v.OS == "Linux" && v.Arch == "64-bit") {
		return false
	}
	switch len(v.Digest) {
	case 64: // SHA256 (newer versions)
	case 40: // SHA1 (older versions)
		return false
	default:
		panic("unexpected digest")
	}
	if v.Kind != "Archive" {
		panic("unexpected kind")
	}
	return true
}

var (
	versionRegexp = regexp.MustCompile(`^(go\d+(?:\.\d+)+)\.`)
)

func getVersion(filename string) (string, error) {
	m := versionRegexp.FindStringSubmatch(filename)
	if len(m) == 0 {
		return "", fmt.Errorf("no match for version")
	}
	return m[1], nil
}

func getDownloadURL(s *goquery.Selection) string {
	aEls := s.Find("a.download")
	if aEls.Length() != 1 {
		panic("xxx")
	}
	href, ok := aEls.Eq(0).Attr("href")
	if !ok {
		panic("xxx")
	}
	return href
}

func main() {
	doc, err := goquery.NewDocument("https://golang.org/dl/")
	if err != nil {
		log.Fatal(err)
	}

	var versions []*DownloadVersion
	doc.Find("table.codetable tr").Each(func(i int, s *goquery.Selection) {
		v := &DownloadVersion{}
		tdEls := s.Find("td")
		if tdEls.Length() < 6 {
			return
		}
		tdEls.Each(func(i int, s *goquery.Selection) {
			switch i {
			case 0:
				v.File = s.Text()
				v.DownloadURL = getDownloadURL(s)
			case 1:
				v.Kind = s.Text()
			case 2:
				v.OS = s.Text()
			case 3:
				v.Arch = s.Text()
			case 4:
				v.Size = s.Text()
			case 5:
				v.Digest = s.Text()
			default:
				panic("unexpected element count")
			}
		})
		if matchesFilter(v) {
			versions = append(versions, v)
		}
	})

	for _, dl := range versions {
		v, err := getVersion(dl.File)
		if err != nil {
			panic(err)
		}
		fmt.Printf("{%q, %q, %q},\n", v, dl.Digest, dl.DownloadURL)
	}
}
