// Copyright 2015 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

//go:build ignore

// This program generates table.go from
// https://www.w3.org/TR/SVG11/types.html#ColorKeywords
package main

import (
	"bytes"
	"fmt"
	"go/format"
	"image/color"
	"io"
	"io/ioutil"
	"log"
	"net/http"
	"regexp"
	"sort"
	"strconv"
	"strings"

	"golang.org/x/net/html"
	"golang.org/x/net/html/atom"
)

// matchFunc matches HTML nodes.
type matchFunc func(*html.Node) bool

// appendAll recursively traverses the parse tree rooted under the provided
// node and appends all nodes matched by the matchFunc to dst.
func appendAll(dst []*html.Node, n *html.Node, mf matchFunc) []*html.Node {
	if mf(n) {
		dst = append(dst, n)
	}
	for c := n.FirstChild; c != nil; c = c.NextSibling {
		dst = appendAll(dst, c, mf)
	}
	return dst
}

// matchAtom returns a matchFunc that matches a Node with the specified Atom.
func matchAtom(a atom.Atom) matchFunc {
	return func(n *html.Node) bool {
		return n.DataAtom == a
	}
}

// matchAtomAttr returns a matchFunc that matches a Node with the specified
// Atom and a html.Attribute's namespace, key and value.
func matchAtomAttr(a atom.Atom, namespace, key, value string) matchFunc {
	return func(n *html.Node) bool {
		return n.DataAtom == a && getAttr(n, namespace, key) == value
	}
}

// getAttr fetches the value of a html.Attribute for a given namespace and key.
func getAttr(n *html.Node, namespace, key string) string {
	for _, attr := range n.Attr {
		if attr.Namespace == namespace && attr.Key == key {
			return attr.Val
		}
	}
	return ""
}

// re extracts RGB values from strings like "rgb( 0, 223, 128)".
var re = regexp.MustCompile(`rgb\(\s*([0-9]+),\s*([0-9]+),\s*([0-9]+)\)`)

// parseRGB parses a color from a string like "rgb( 0, 233, 128)". It sets
// the alpha value of the color to full opacity.
func parseRGB(s string) (color.RGBA, error) {
	m := re.FindStringSubmatch(s)
	if m == nil {
		return color.RGBA{}, fmt.Errorf("malformed color: %q", s)
	}
	var rgb [3]uint8
	for i, t := range m[1:] {
		num, err := strconv.ParseUint(t, 10, 8)
		if err != nil {
			return color.RGBA{}, fmt.Errorf("malformed value %q in %q: %s", t, s, err)
		}
		rgb[i] = uint8(num)
	}
	return color.RGBA{rgb[0], rgb[1], rgb[2], 0xFF}, nil
}

// extractSVGColors extracts named colors from the parse tree of the SVG 1.1
// spec HTML document "Chapter 4: Basic data types and interfaces".
func extractSVGColors(tree *html.Node) (map[string]color.RGBA, error) {
	ret := make(map[string]color.RGBA)

	// Find the tables which store the color keywords in the parse tree.
	colorTables := appendAll(nil, tree, func(n *html.Node) bool {
		return n.DataAtom == atom.Table && strings.Contains(getAttr(n, "", "summary"), "color keywords part")
	})

	for _, table := range colorTables {
		// Color names and values are stored in TextNodes within spans in each row.
		for _, tr := range appendAll(nil, table, matchAtom(atom.Tr)) {
			nameSpan := appendAll(nil, tr, matchAtomAttr(atom.Span, "", "class", "prop-value"))
			valueSpan := appendAll(nil, tr, matchAtomAttr(atom.Span, "", "class", "color-keyword-value"))

			// Since SVG 1.1 defines an odd number of colors, the last row
			// in the second table does not have contents. We skip it.
			if len(nameSpan) != 1 || len(valueSpan) != 1 {
				continue
			}
			n, v := nameSpan[0].FirstChild, valueSpan[0].FirstChild
			// This sanity checks for the existence of TextNodes under spans.
			if n == nil || n.Type != html.TextNode || v == nil || v.Type != html.TextNode {
				return nil, fmt.Errorf("extractSVGColors: couldn't find name/value text nodes")
			}
			val, err := parseRGB(v.Data)
			if err != nil {
				return nil, fmt.Errorf("extractSVGColors: couldn't parse name/value %q/%q: %s", n.Data, v.Data, err)
			}
			ret[n.Data] = val
		}
	}
	return ret, nil
}

const preamble = `// generated by go generate; DO NOT EDIT.

package colornames

import "image/color"

`

// WriteColorNames writes table.go.
func writeColorNames(w io.Writer, m map[string]color.RGBA) {
	keys := make([]string, 0, len(m))
	for k := range m {
		keys = append(keys, k)
	}
	sort.Strings(keys)

	fmt.Fprintln(w, preamble)
	fmt.Fprintln(w, "// Map contains named colors defined in the SVG 1.1 spec.")
	fmt.Fprintln(w, "var Map = map[string]color.RGBA{")
	for _, k := range keys {
		c := m[k]
		fmt.Fprintf(w, "%q:color.RGBA{%#02x, %#02x, %#02x, %#02x}, // rgb(%d, %d, %d)\n",
			k, c.R, c.G, c.B, c.A, c.R, c.G, c.B)
	}
	fmt.Fprintln(w, "}\n")
	fmt.Fprintln(w, "// Names contains the color names defined in the SVG 1.1 spec.")
	fmt.Fprintln(w, "var Names = []string{")
	for _, k := range keys {
		fmt.Fprintf(w, "%q,\n", k)
	}
	fmt.Fprintln(w, "}\n")
	fmt.Fprintln(w, "var (")
	for _, k := range keys {
		c := m[k]
		// Make the upper case version of k: "Darkred" instead of "darkred".
		k = string(k[0]-0x20) + k[1:]
		fmt.Fprintf(w, "%s=color.RGBA{%#02x, %#02x, %#02x, %#02x} // rgb(%d, %d, %d)\n",
			k, c.R, c.G, c.B, c.A, c.R, c.G, c.B)
	}
	fmt.Fprintln(w, ")")
}

const url = "https://www.w3.org/TR/SVG11/types.html"

func main() {
	res, err := http.Get(url)
	if err != nil {
		log.Fatalf("Couldn't read from %s: %s\n", url, err)
	}
	defer res.Body.Close()

	tree, err := html.Parse(res.Body)
	if err != nil {
		log.Fatalf("Couldn't parse %s: %s\n", url, err)
	}

	colors, err := extractSVGColors(tree)
	if err != nil {
		log.Fatalf("Couldn't extract colors: %s\n", err)
	}

	buf := &bytes.Buffer{}
	writeColorNames(buf, colors)
	fmted, err := format.Source(buf.Bytes())
	if err != nil {
		log.Fatalf("Error while formatting code: %s\n", err)
	}

	if err := ioutil.WriteFile("table.go", fmted, 0644); err != nil {
		log.Fatalf("Error writing table.go: %s\n", err)
	}
}
