// Copyright 2016 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

package main

import (
	"bytes"
	"encoding/xml"
	"errors"
	"flag"
	"fmt"
	"go/format"
	"io"
	"io/ioutil"
	"log"
	"os"
	"path"
	"path/filepath"
	"sort"
	"strconv"
	"strings"

	"golang.org/x/exp/shiny/iconvg"
	"golang.org/x/image/math/f32"
)

var mdicons = flag.String("mdicons", "", "The directory on the local file system where "+
	"https://github.com/google/material-design-icons was checked out",
)

// outSize is the width and height (in ideal vector space) of the generated
// IconVG graphic, regardless of the size of the input SVG.
const outSize = 48

// errSkip deliberately skips generating an icon.
//
// When manually debugging one particular icon, it can be useful to add
// something like:
// 	if baseName != "check_box" { return errSkip }
// at the top of func genFile.
var errSkip = errors.New("skipping SVG to IconVG conversion")

var (
	out      = new(bytes.Buffer)
	failures = []string{}
	varNames = []string{}

	totalFiles      int
	totalIVGBytes   int
	totalPNG24Bytes int
	totalPNG48Bytes int
	totalSVGBytes   int
)

var acronyms = map[string]string{
	"3d":            "3D",
	"ac":            "AC",
	"adb":           "ADB",
	"airplanemode":  "AirplaneMode",
	"atm":           "ATM",
	"av":            "AV",
	"ccw":           "CCW",
	"cw":            "CW",
	"din":           "DIN",
	"dns":           "DNS",
	"dvr":           "DVR",
	"eta":           "ETA",
	"ev":            "EV",
	"gif":           "GIF",
	"gps":           "GPS",
	"hd":            "HD",
	"hdmi":          "HDMI",
	"hdr":           "HDR",
	"http":          "HTTP",
	"https":         "HTTPS",
	"iphone":        "IPhone",
	"iso":           "ISO",
	"jpeg":          "JPEG",
	"markunread":    "MarkUnread",
	"mms":           "MMS",
	"nfc":           "NFC",
	"ondemand":      "OnDemand",
	"pdf":           "PDF",
	"phonelink":     "PhoneLink",
	"png":           "PNG",
	"rss":           "RSS",
	"rv":            "RV",
	"sd":            "SD",
	"sim":           "SIM",
	"sip":           "SIP",
	"sms":           "SMS",
	"streetview":    "StreetView",
	"svideo":        "SVideo",
	"textdirection": "TextDirection",
	"textsms":       "TextSMS",
	"timelapse":     "TimeLapse",
	"toc":           "TOC",
	"tv":            "TV",
	"usb":           "USB",
	"vpn":           "VPN",
	"wb":            "WB",
	"wc":            "WC",
	"whatshot":      "WhatsHot",
	"wifi":          "WiFi",
}

func upperCase(s string) string {
	if a, ok := acronyms[s]; ok {
		return a
	}
	if c := s[0]; 'a' <= c && c <= 'z' {
		return string(c-0x20) + s[1:]
	}
	return s
}

func main() {
	flag.Parse()

	out.WriteString("// generated by go run gen.go; DO NOT EDIT\n\npackage icons\n\n")

	f, err := os.Open(*mdicons)
	if err != nil {
		log.Fatalf("%v\n\nDid you override the -mdicons flag in icons.go?\n\n", err)
	}
	defer f.Close()
	infos, err := f.Readdir(-1)
	if err != nil {
		log.Fatal(err)
	}
	names := []string{}
	for _, info := range infos {
		if !info.IsDir() {
			continue
		}
		name := info.Name()
		if name[0] == '.' {
			continue
		}
		names = append(names, name)
	}
	sort.Strings(names)
	for _, name := range names {
		genDir(name)
	}

	fmt.Fprintf(out,
		"// In total, %d SVG bytes in %d files (%d PNG bytes at 24px * 24px,\n"+
			"// %d PNG bytes at 48px * 48px) converted to %d IconVG bytes.\n",
		totalSVGBytes, totalFiles, totalPNG24Bytes, totalPNG48Bytes, totalIVGBytes)

	if len(failures) != 0 {
		out.WriteString("\n/*\nFAILURES:\n\n")
		for _, failure := range failures {
			out.WriteString(failure)
			out.WriteByte('\n')
		}
		out.WriteString("\n*/")
	}

	raw := out.Bytes()
	formatted, err := format.Source(raw)
	if err != nil {
		log.Fatalf("gofmt failed: %v\n\nGenerated code:\n%s", err, raw)
	}
	if err := ioutil.WriteFile("data.go", formatted, 0644); err != nil {
		log.Fatalf("WriteFile failed: %s\n", err)
	}

	// Generate data_test.go. The code immediately above generates data.go.
	{
		b := new(bytes.Buffer)
		b.WriteString("// generated by go run gen.go; DO NOT EDIT\n\npackage icons\n\n")
		b.WriteString("var list = []struct{ name string; data []byte } {\n")
		for _, v := range varNames {
			fmt.Fprintf(b, "{%q, %s},\n", v, v)
		}
		b.WriteString("}\n\n")
		raw := b.Bytes()
		formatted, err := format.Source(raw)
		if err != nil {
			log.Fatalf("gofmt failed: %v\n\nGenerated code:\n%s", err, raw)
		}
		if err := ioutil.WriteFile("data_test.go", formatted, 0644); err != nil {
			log.Fatalf("WriteFile failed: %s\n", err)
		}
	}
}

func genDir(dirName string) {
	fqPNGDirName := filepath.FromSlash(path.Join(*mdicons, dirName, "1x_web"))
	fqSVGDirName := filepath.FromSlash(path.Join(*mdicons, dirName, "svg/production"))
	f, err := os.Open(fqSVGDirName)
	if err != nil {
		return
	}
	defer f.Close()

	infos, err := f.Readdir(-1)
	if err != nil {
		log.Fatal(err)
	}
	baseNames, fileNames, sizes := []string{}, map[string]string{}, map[string]int{}
	for _, info := range infos {
		name := info.Name()

		if !strings.HasPrefix(name, "ic_") || skippedFiles[[2]string{dirName, name}] {
			continue
		}
		size := 0
		switch {
		case strings.HasSuffix(name, "_12px.svg"):
			size = 12
		case strings.HasSuffix(name, "_18px.svg"):
			size = 18
		case strings.HasSuffix(name, "_24px.svg"):
			size = 24
		case strings.HasSuffix(name, "_36px.svg"):
			size = 36
		case strings.HasSuffix(name, "_48px.svg"):
			size = 48
		default:
			continue
		}

		baseName := name[3 : len(name)-9]
		if prevSize, ok := sizes[baseName]; ok {
			if size > prevSize {
				fileNames[baseName] = name
				sizes[baseName] = size
			}
		} else {
			fileNames[baseName] = name
			sizes[baseName] = size
			baseNames = append(baseNames, baseName)
		}
	}

	sort.Strings(baseNames)
	for _, baseName := range baseNames {
		fileName := fileNames[baseName]
		err := genFile(fqSVGDirName, dirName, baseName, fileName, float32(sizes[baseName]))
		if err == errSkip {
			continue
		}
		if err != nil {
			failures = append(failures, fmt.Sprintf("%v/svg/production/%v: %v", dirName, fileName, err))
			continue
		}
		totalPNG24Bytes += pngSize(fqPNGDirName, dirName, baseName, 24)
		totalPNG48Bytes += pngSize(fqPNGDirName, dirName, baseName, 48)
	}
}

func pngSize(fqPNGDirName, dirName, baseName string, targetSize int) int {
	for _, size := range [...]int{48, 24, 18} {
		if size > targetSize {
			continue
		}
		fInfo, err := os.Stat(filepath.Join(fqPNGDirName,
			fmt.Sprintf("ic_%s_black_%ddp.png", baseName, size)))
		if err != nil {
			continue
		}
		return int(fInfo.Size())
	}
	failures = append(failures,
		fmt.Sprintf("no PNG found for %s/1x_web/ic_%s_black_{48,24,18}dp.png", dirName, baseName))
	return 0
}

type SVG struct {
	Width   float32 `xml:"where,attr"`
	Height  float32 `xml:"height,attr"`
	ViewBox string  `xml:"viewBox,attr"`
	Paths   []Path  `xml:"path"`
	// Some of the SVG files contain <circle> elements, not just <path>
	// elements. IconVG doesn't have circles per se. Instead, we convert such
	// circles to be paired arcTo commands, tacked on to the first path.
	//
	// In general, this isn't correct if the circles and the path overlap, but
	// that doesn't happen in the specific case of the Material Design icons.
	Circles []Circle `xml:"circle"`
}

type Path struct {
	D           string   `xml:"d,attr"`
	Fill        string   `xml:"fill,attr"`
	FillOpacity *float32 `xml:"fill-opacity,attr"`
	Opacity     *float32 `xml:"opacity,attr"`
}

type Circle struct {
	Cx float32 `xml:"cx,attr"`
	Cy float32 `xml:"cy,attr"`
	R  float32 `xml:"r,attr"`
}

var skippedPaths = map[string]string{
	// hardware/svg/production/ic_scanner_48px.svg contains a filled white
	// rectangle that is overwritten by the subsequent path.
	//
	// See https://github.com/google/material-design-icons/issues/490
	//
	// Matches <path fill="#fff" d="M16 34h22v4H16z"/>
	"M16 34h22v4H16z": "#fff",

	// device/svg/production/ic_airplanemode_active_48px.svg and
	// maps/svg/production/ic_flight_48px.svg contain a degenerate path that
	// contains only one moveTo op.
	//
	// See https://github.com/google/material-design-icons/issues/491
	//
	// Matches <path d="M20.36 18"/>
	"M20.36 18": "",
}

var skippedFiles = map[[2]string]bool{
	// ic_play_circle_filled_white_48px.svg is just the same as
	// ic_play_circle_filled_48px.svg with an explicit fill="#fff".
	{"av", "ic_play_circle_filled_white_48px.svg"}: true,
}

func genFile(fqSVGDirName, dirName, baseName, fileName string, size float32) error {
	fqFileName := filepath.Join(fqSVGDirName, fileName)
	svgData, err := ioutil.ReadFile(fqFileName)
	if err != nil {
		return err
	}

	varName := upperCase(dirName)
	for _, s := range strings.Split(baseName, "_") {
		varName += upperCase(s)
	}
	fmt.Fprintf(out, "var %s = []byte{", varName)
	defer fmt.Fprintf(out, "\n}\n\n")
	varNames = append(varNames, varName)

	var enc iconvg.Encoder
	enc.Reset(iconvg.Metadata{
		ViewBox: iconvg.Rectangle{
			Min: f32.Vec2{-24, -24},
			Max: f32.Vec2{+24, +24},
		},
		Palette: iconvg.DefaultPalette,
	})

	g := &SVG{}
	if err := xml.Unmarshal(svgData, g); err != nil {
		return err
	}

	var vbx, vby float32
	for i, v := range strings.Split(g.ViewBox, " ") {
		f, err := strconv.ParseFloat(v, 32)
		if err != nil {
			return err
		}
		switch i {
		case 0:
			vbx = float32(f)
		case 1:
			vby = float32(f)
		}
	}
	offset := f32.Vec2{
		vbx * outSize / size,
		vby * outSize / size,
	}

	// adjs maps from opacity to a cReg adj value.
	adjs := map[float32]uint8{}

	for _, p := range g.Paths {
		if fill, ok := skippedPaths[p.D]; ok && fill == p.Fill {
			continue
		}
		if err := genPath(&enc, &p, adjs, size, offset, g.Circles); err != nil {
			return err
		}
		g.Circles = nil
	}

	if len(g.Circles) != 0 {
		if err := genPath(&enc, &Path{}, adjs, size, offset, g.Circles); err != nil {
			return err
		}
		g.Circles = nil
	}

	ivgData, err := enc.Bytes()
	if err != nil {
		return err
	}
	for i, x := range ivgData {
		if i&0x0f == 0x00 {
			out.WriteByte('\n')
		}
		fmt.Fprintf(out, "%#02x, ", x)
	}

	totalFiles++
	totalSVGBytes += len(svgData)
	totalIVGBytes += len(ivgData)
	return nil
}

func genPath(enc *iconvg.Encoder, p *Path, adjs map[float32]uint8, size float32, offset f32.Vec2, circles []Circle) error {
	adj := uint8(0)
	opacity := float32(1)
	if p.Opacity != nil {
		opacity = *p.Opacity
	} else if p.FillOpacity != nil {
		opacity = *p.FillOpacity
	}
	if opacity != 1 {
		var ok bool
		if adj, ok = adjs[opacity]; !ok {
			adj = uint8(len(adjs) + 1)
			adjs[opacity] = adj
			// Set CREG[0-adj] to be a blend of transparent (0x7f) and the
			// first custom palette color (0x80).
			enc.SetCReg(adj, false, iconvg.BlendColor(uint8(opacity*0xff), 0x7f, 0x80))
		}
	}

	needStartPath := true
	if p.D != "" {
		needStartPath = false
		if err := genPathData(enc, adj, p.D, size, offset); err != nil {
			return err
		}
	}

	for _, c := range circles {
		// Normalize.
		cx := c.Cx * outSize / size
		cx -= outSize/2 + offset[0]
		cy := c.Cy * outSize / size
		cy -= outSize/2 + offset[1]
		r := c.R * outSize / size

		if needStartPath {
			needStartPath = false
			enc.StartPath(adj, cx-r, cy)
		} else {
			enc.ClosePathAbsMoveTo(cx-r, cy)
		}

		// Convert a circle to two relative arcTo ops, each of 180 degrees.
		// We can't use one 360 degree arcTo as the start and end point
		// would be coincident and the computation is degenerate.
		enc.RelArcTo(r, r, 0, false, true, +2*r, 0)
		enc.RelArcTo(r, r, 0, false, true, -2*r, 0)
	}

	enc.ClosePathEndPath()
	return nil
}

func genPathData(enc *iconvg.Encoder, adj uint8, pathData string, size float32, offset f32.Vec2) error {
	if strings.HasSuffix(pathData, "z") {
		pathData = pathData[:len(pathData)-1]
	}
	r := strings.NewReader(pathData)

	var args [6]float32
	op, relative, started := byte(0), false, false
	for {
		b, err := r.ReadByte()
		if err == io.EOF {
			break
		}
		if err != nil {
			return err
		}

		switch {
		case b == ' ':
			continue
		case 'A' <= b && b <= 'Z':
			op, relative = b, false
		case 'a' <= b && b <= 'z':
			op, relative = b, true
		default:
			r.UnreadByte()
		}

		n := 0
		switch op {
		case 'L', 'l', 'T', 't':
			n = 2
		case 'Q', 'q', 'S', 's':
			n = 4
		case 'C', 'c':
			n = 6
		case 'H', 'h', 'V', 'v':
			n = 1
		case 'M', 'm':
			n = 2
		case 'Z', 'z':
		default:
			return fmt.Errorf("unknown opcode %c\n", b)
		}

		scan(&args, r, n)
		normalize(&args, n, op, size, offset, relative)

		switch op {
		case 'L':
			enc.AbsLineTo(args[0], args[1])
		case 'l':
			enc.RelLineTo(args[0], args[1])
		case 'T':
			enc.AbsSmoothQuadTo(args[0], args[1])
		case 't':
			enc.RelSmoothQuadTo(args[0], args[1])
		case 'Q':
			enc.AbsQuadTo(args[0], args[1], args[2], args[3])
		case 'q':
			enc.RelQuadTo(args[0], args[1], args[2], args[3])
		case 'S':
			enc.AbsSmoothCubeTo(args[0], args[1], args[2], args[3])
		case 's':
			enc.RelSmoothCubeTo(args[0], args[1], args[2], args[3])
		case 'C':
			enc.AbsCubeTo(args[0], args[1], args[2], args[3], args[4], args[5])
		case 'c':
			enc.RelCubeTo(args[0], args[1], args[2], args[3], args[4], args[5])
		case 'H':
			enc.AbsHLineTo(args[0])
		case 'h':
			enc.RelHLineTo(args[0])
		case 'V':
			enc.AbsVLineTo(args[0])
		case 'v':
			enc.RelVLineTo(args[0])
		case 'M':
			if !started {
				started = true
				enc.StartPath(adj, args[0], args[1])
			} else {
				enc.ClosePathAbsMoveTo(args[0], args[1])
			}
		case 'm':
			enc.ClosePathRelMoveTo(args[0], args[1])
		}
	}
	return nil
}

func scan(args *[6]float32, r *strings.Reader, n int) {
	for i := 0; i < n; i++ {
		for {
			if b, _ := r.ReadByte(); b != ' ' {
				r.UnreadByte()
				break
			}
		}
		fmt.Fscanf(r, "%f", &args[i])
	}
}

func atof(s []byte) (float32, error) {
	f, err := strconv.ParseFloat(string(s), 32)
	if err != nil {
		return 0, fmt.Errorf("could not parse %q as a float32: %v", s, err)
	}
	return float32(f), err
}

func normalize(args *[6]float32, n int, op byte, size float32, offset f32.Vec2, relative bool) {
	for i := 0; i < n; i++ {
		args[i] *= outSize / size
		if relative {
			continue
		}
		args[i] -= outSize / 2
		switch {
		case n != 1:
			args[i] -= offset[i&0x01]
		case op == 'H':
			args[i] -= offset[0]
		case op == 'V':
			args[i] -= offset[1]
		}
	}
}
