// 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
// +build ignore

// This program generates table.go from
// https://material.google.com/style/color.html
package main

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

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

type matchFunc func(*html.Node) bool

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
}

func match(a atom.Atom, namespace, key, value string) matchFunc {
	return func(n *html.Node) bool {
		return n.DataAtom == a && strings.HasPrefix(getAttr(n, namespace, key), value)
	}
}

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 ""
}

func getText(n *html.Node) string {
	if n.FirstChild == nil || n.FirstChild.Type != html.TextNode {
		return ""
	}
	return n.FirstChild.Data
}

var unhex = [256]byte{
	'0': 0,
	'1': 1,
	'2': 2,
	'3': 3,
	'4': 4,
	'5': 5,
	'6': 6,
	'7': 7,
	'8': 8,
	'9': 9,
	'a': 10,
	'b': 11,
	'c': 12,
	'd': 13,
	'e': 14,
	'f': 15,
}

func parseRGB(s string) color.RGBA {
	if len(s) != 7 || s[0] != '#' {
		return color.RGBA{}
	}
	return color.RGBA{
		R: unhex[s[1]]<<4 | unhex[s[2]],
		G: unhex[s[3]]<<4 | unhex[s[4]],
		B: unhex[s[5]]<<4 | unhex[s[6]],
		A: 0xff,
	}
}

type entry struct {
	name string
	rgba color.RGBA
}

func extractColors(tree *html.Node) (ret []entry) {
	for _, table := range appendAll(nil, tree, match(atom.Section, "", "class", "color-group")) {
		name := ""
		for _, nameNode := range appendAll(nil, table, match(atom.Span, "", "class", "name")) {
			name = strings.Replace(getText(nameNode), " ", "", -1)
			break
		}
		shades := appendAll(nil, table, match(atom.Span, "", "class", "shade"))
		hexes := appendAll(nil, table, match(atom.Span, "", "class", "hex"))
		if len(shades) != len(hexes) || len(shades) == 0 {
			continue
		}
		// Remove the duplicated 500 shade at the start of the list.
		if getText(shades[0]) == "500" {
			shades, hexes = shades[1:], hexes[1:]
		}
		for i, shade := range shades {
			ret = append(ret, entry{
				name + getText(shade),
				parseRGB(getText(hexes[i])),
			})
		}
	}
	return ret
}

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

package colornames

import "image/color"

`

func writeColorNames(w io.Writer, entries []entry) {
	fmt.Fprintln(w, preamble)
	fmt.Fprintln(w, "// Map contains named colors defined in the Material Design style guide.")
	fmt.Fprintln(w, "var Map = map[string]color.RGBA{")
	for _, e := range entries {
		c := e.rgba
		fmt.Fprintf(w, "%q:color.RGBA{%#02x, %#02x, %#02x, %#02x}, // rgb(%d, %d, %d)\n",
			e.name, 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 Material Design style guide.")
	fmt.Fprintln(w, "var Names = []string{")
	for _, e := range entries {
		fmt.Fprintf(w, "%q,\n", e.name)
	}
	fmt.Fprintln(w, "}\n")
	fmt.Fprintln(w, "var (")
	for _, e := range entries {
		c := e.rgba
		fmt.Fprintf(w, "%s=color.RGBA{%#02x, %#02x, %#02x, %#02x} // rgb(%d, %d, %d)\n",
			e.name, c.R, c.G, c.B, c.A, c.R, c.G, c.B)
	}
	fmt.Fprintln(w, ")")
}

const url = "https://material.google.com/style/color.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)
	}

	buf := &bytes.Buffer{}
	writeColorNames(buf, extractColors(tree))
	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)
	}
}
