// Copyright (c) 2017, Shreyas Khare <skhare@rapid7.com>
// See LICENSE for licensing information

package main

import (
	"encoding/csv"
	"io"
	"log"
	"net/http"
	"os"
	"strings"
	"text/template"
)

const path = "schemes.go"

var schemesTmpl = template.Must(template.New("schemes").Parse(`// Generated by schemesgen

package xurls

// Schemes is a sorted list of all IANA assigned schemes.
//
// Source: https://www.iana.org/assignments/uri-schemes/uri-schemes-1.csv
var Schemes = []string{
{{range $scheme := .Schemes}}` + "\t`" + `{{$scheme}}` + "`" + `,
{{end}}}
`))

func schemeList() []string {
	resp, err := http.Get("https://www.iana.org/assignments/uri-schemes/uri-schemes-1.csv")
	if err != nil {
		log.Fatal(err)
	}
	defer resp.Body.Close()
	r := csv.NewReader(resp.Body)
	r.Read() // ignore headers
	schemes := make([]string, 0)
	for {
		record, err := r.Read()
		if err == io.EOF {
			break
		}
		if err != nil {
			log.Fatal(err)
		}
		if strings.Contains(record[0], "OBSOLETE") {
			continue // skip obsolete schemes; note the scheme column is abused
		}
		schemes = append(schemes, record[0])
	}
	return schemes
}

func writeSchemes(schemes []string) error {
	f, err := os.Create(path)
	if err != nil {
		return err
	}
	defer f.Close()
	return schemesTmpl.Execute(f, struct {
		Schemes []string
	}{
		Schemes: schemes,
	})
}

func main() {
	schemes := schemeList()
	log.Printf("Generating %s...", path)
	if err := writeSchemes(schemes); err != nil {
		log.Fatalf("Could not write path: %v", err)
	}
}
