// 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"
	"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 := os.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 := os.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 := os.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]
		}
	}
}
