// Copyright 2021 The Tint Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// This tool parses WGSL specification and outputs WGSL rules.
//
// To run from root of tint repo:
//   go get golang.org/x/net/html # Only required once
// Then run
//   ./tools/get-test-plan --spec=<path-to-spec-file-or-url> --output=<path-to-output-file>
// Or run
//   cd tools/src &&  go run cmd/get-spec-rules/main.go --output=<path-to-output-file>
//
// To see help
//   ./tools/get-test-plan --help

package main

import (
	"crypto/sha1"
	"encoding/json"
	"errors"
	"flag"
	"fmt"
	"io"
	"io/ioutil"
	"net/http"
	"net/url"
	"os"
	"path/filepath"
	"regexp"
	"strconv"
	"strings"

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

const (
	toolName        = "get-test-plan"
	specPath        = "https://www.w3.org/TR/WGSL/"
	specVersionUsed = "https://www.w3.org/TR/2021/WD-WGSL-20210929/"
)

var (
	errInvalidArg  = errors.New("invalid arguments")
	headURL        = specVersionUsed
	markedNodesSet = make(map[*html.Node]bool)
	testNamesSet   = make(map[string]bool)
	sha1sSet       = make(map[string]bool)
	keywords       = []string{
		"MUST ", "MUST NOT ", "REQUIRED ", "SHALL ",
		"SHALL NOT ", "SHOULD ", "SHOULD NOT ",
		"RECOMMENDED ", "MAY ", "OPTIONAL ",
	}
	globalSection      = ""
	globalPrevSectionX = -1
	globalRuleCounter  = 0
)

// Holds all the information about a WGSL rule
type rule struct {
	Number      int    // The index of this obj in an array of 'rules'
	Section     int    // The section this rule belongs to
	SubSection  string // The section this rule belongs to
	URL         string // The section's URL of this rule
	Description string // The rule's description
	TestName    string // The suggested test name to use when writing CTS
	Keyword     string // The keyword e.g. MUST, ALGORITHM, ..., i.e. Indicating why the rule is added
	Desc        []string
	Sha         string
}

func main() {
	flag.Usage = func() {
		out := flag.CommandLine.Output()
		fmt.Fprintf(out, "%v parses WGSL spec and outputs a test plan\n", toolName)
		fmt.Fprintf(out, "\n")
		fmt.Fprintf(out, "Usage:\n")
		fmt.Fprintf(out, "  %s [spec] [flags]\n", toolName)
		fmt.Fprintf(out, "\n")
		fmt.Fprintf(out, "spec is an optional local file or a URL to the WGSL specification.\n")
		fmt.Fprintf(out, "If spec is omitted then the specification is fetched from %v\n\n", specPath)

		fmt.Fprintf(out, "this tools is developed based on: %v\n", specVersionUsed)
		fmt.Fprintf(out, "flags may be any combination of:\n")
		flag.PrintDefaults()
	}

	err := run()
	switch err {
	case nil:
		return
	case errInvalidArg:
		fmt.Fprintf(os.Stderr, "Error: %v\n\n", err)
		flag.Usage()
	default:
		fmt.Fprintf(os.Stderr, "%v\n", err)
	}
	os.Exit(1)
}

func run() error {
	// Parse flags
	keyword := flag.String("keyword", "",
		`if provided, it will be used as the keyword to search WGSL spec for rules
if omitted, the keywords indicated in RFC 2119 requirement are used,
in addition to nodes containing a nowrap or an algorithm tag eg. <tr algorithm=...>`)

	ctsDir := flag.String("cts-directory", "",
		`if provided:
    validation cts test plan will be written to: '<cts-directory>/validation/'
    builtin functions cts test plan will be written to: '<cts-directory>/execution/builtin'`)

	output := flag.String("output", "",
		`if file extension is 'txt' the output format will be a human readable text
if file extension is 'tsv' the output format will be a tab separated file
if file extension is 'json' the output format will be json
if omitted, a human readable version of the rules is written to stdout`)

	testNameFilter := flag.String("test-name-filter", "",
		`if provided will be used to filter reported rules based on if their name
contains the provided string`)

	flag.Parse()

	args := flag.Args()

	// Parse spec
	spec, err := parseSpec(args)
	if err != nil {
		return err
	}

	// Set keywords
	if *keyword != "" {
		keywords = []string{*keyword}
	}

	parser, err := Parse(spec)
	if err != nil {
		return err
	}
	rules := parser.rules

	if *ctsDir != "" {
		err := getUnimplementedTestPlan(*parser, *ctsDir)
		if err != nil {
			return err
		}
	}

	txt, tsv := concatRules(rules, *testNameFilter)
	// if no output then write rules to stdout
	if *output == "" {
		fmt.Println(txt)
		// write concatenated rules to file
	} else if strings.HasSuffix(*output, ".json") {
		j, err := json.Marshal(rules)
		if err != nil {
			return err
		}
		return writeFile(*output, string(j))
	} else if strings.HasSuffix(*output, ".txt") {
		return writeFile(*output, txt)
	} else if strings.HasSuffix(*output, ".tsv") {
		return writeFile(*output, tsv)
	} else {
		return fmt.Errorf("unsupported output file extension: %v", *output)
	}
	return nil
}

// getSectionRange scans all the rules and returns the rule index interval of a given section.
// The sections range is the interval: rules[start:end].
// example: section = [x, y, z] i.e. x.y.z(.w)* it returns (start = min(w),end = max(w))
// if there are no rules extracted from x.y.z it returns (-1, -1)
func getSectionRange(rules []rule, s []int) (start, end int, err error) {
	start = -1
	end = -1
	for _, r := range rules {
		sectionDims, err := parseSection(r.SubSection)
		if err != nil {
			return -1, -1, err
		}

		ruleIsInSection := true
		for i := range s {
			if sectionDims[i] != s[i] {
				ruleIsInSection = false
				break
			}
		}
		if !ruleIsInSection {
			continue
		}

		dim := -1
		if len(sectionDims) == len(s) {
			//x.y is the same as x.y.0
			dim = 0
		} else if len(sectionDims) > len(s) {
			dim = sectionDims[len(s)]
		} else {
			continue
		}

		if start == -1 {
			start = dim
		}
		if dim > end {
			end = dim
		}
	}

	if start == -1 || end == -1 {
		return -1, -1, fmt.Errorf("cannot determine section range")
	}

	return start, end, nil
}

// parseSection return the numbers for any dot-separated string of numbers
// example: x.y.z.w returns [x, y, z, w]
// returns an error if the string does not match "^\d(.\d)*$"
func parseSection(in string) ([]int, error) {
	parts := strings.Split(in, ".")
	out := make([]int, len(parts))
	for i, part := range parts {
		var err error
		out[i], err = strconv.Atoi(part)
		if err != nil {
			return nil, fmt.Errorf(`cannot parse sections string "%v": %w`, in, err)
		}
	}
	return out, nil
}

// concatRules concatenate rules slice to make two string outputs;
//   txt, a human-readable string
//   tsv, a tab separated string
// If testNameFilter is a non-empty string, then only rules whose TestName
// contains the string are included
func concatRules(rules []rule, testNameFilter string) (string, string) {
	txtLines := []string{}
	tsvLines := []string{"Number\tUniqueId\tSection\tURL\tDescription\tProposed Test Name\tkeyword"}

	for _, r := range rules {
		if testNameFilter != "" && !strings.Contains(r.TestName, testNameFilter) {
			continue
		}

		txtLines = append(txtLines, strings.Join([]string{
			"Rule Number " + strconv.Itoa(r.Number) + ":",
			"Unique Id: " + r.Sha,
			"Section: " + r.SubSection,
			"Keyword: " + r.Keyword,
			"testName: " + r.TestName,
			"URL: " + r.URL,
			r.Description,
			"---------------------------------------------------"}, "\n"))

		tsvLines = append(tsvLines, strings.Join([]string{
			strconv.Itoa(r.Number),
			r.Sha,
			r.SubSection,
			r.URL,
			strings.Trim(r.Description, "\n\t "),
			r.Keyword,
			r.TestName}, "\t"))
	}
	txt := strings.Join(txtLines, "\n")
	tsv := strings.Join(tsvLines, "\n")
	return txt, tsv
}

// writeFile writes content to path
// the existing content will be overwritten
func writeFile(path, content string) error {
	if err := os.MkdirAll(filepath.Dir(path), 0777); err != nil {
		return fmt.Errorf("failed to create directory for '%v': %w", path, err)
	}
	if err := ioutil.WriteFile(path, []byte(content), 0666); err != nil {
		return fmt.Errorf("failed to write file '%v': %w", path, err)
	}
	return nil
}

// parseSpec reads the spec from a local file, or the URL to WGSL spec
func parseSpec(args []string) (*html.Node, error) {
	// Check for explicit WGSL spec path
	specURL, _ := url.Parse(specPath)
	switch len(args) {
	case 0:
	case 1:
		var err error
		specURL, err = url.Parse(args[0])
		if err != nil {
			return nil, err
		}
	default:
		if len(args) > 1 {
			return nil, errInvalidArg
		}
	}

	// The specURL might just be a local file path, in which case automatically
	// add the 'file' URL scheme
	if specURL.Scheme == "" {
		specURL.Scheme = "file"
	}

	// Open the spec from HTTP(S) or from a local file
	var specContent io.ReadCloser
	switch specURL.Scheme {
	case "http", "https":
		response, err := http.Get(specURL.String())
		if err != nil {
			return nil, fmt.Errorf("failed to load the WGSL spec from '%v': %w", specURL, err)
		}
		specContent = response.Body
	case "file":
		path, err := filepath.Abs(specURL.Path)
		if err != nil {
			return nil, fmt.Errorf("failed to load the WGSL spec from '%v': %w", specURL, err)
		}

		file, err := os.Open(path)
		if err != nil {
			return nil, fmt.Errorf("failed to load the WGSL spec from '%v': %w", specURL, err)
		}
		specContent = file
	default:
		return nil, fmt.Errorf("unsupported URL scheme: %v", specURL.Scheme)
	}
	defer specContent.Close()

	// Open the spec from HTTP(S) or from a local file
	switch specURL.Scheme {
	case "http", "https":
		response, err := http.Get(specURL.String())
		if err != nil {
			return nil, fmt.Errorf("failed to load the WGSL spec from '%v': %w", specURL, err)
		}
		specContent = response.Body

	case "file":
		path, err := filepath.Abs(specURL.Path)
		if err != nil {
			return nil, fmt.Errorf("failed to load the WGSL spec from '%v': %w", specURL, err)
		}
		file, err := os.Open(path)
		if err != nil {
			return nil, fmt.Errorf("failed to load the WGSL spec from '%v': %w", specURL, err)
		}
		specContent = file

	default:
		return nil, fmt.Errorf("unsupported URL scheme: %v", specURL.Scheme)
	}
	defer specContent.Close()

	// Parse spec
	spec, err := html.Parse(specContent)
	if err != nil {
		return spec, err
	}
	return spec, nil
}

// containsKeyword returns (true, 'kw'), if input string 'data' contains an
// element of the string list, otherwise it returns (false, "")
// search is not case-sensitive
func containsKeyword(data string, list []string) (bool, string) {
	for _, kw := range list {
		if strings.Contains(
			strings.ToLower(data),
			strings.ToLower(kw),
		) {
			return true, kw
		}
	}
	return false, ""
}

// Parser holds the information extracted from the spec
// TODO(sarahM0): https://bugs.c/tint/1149/ clean up the vars holding section information
type Parser struct {
	rules                      []rule // a slice to store the rules extracted from the spec
	firstSectionContainingRule int    // the first section a rules is extracted from
	lastSectionContainingRule  int    // the last section a rules is extracted form
}

func Parse(node *html.Node) (*Parser, error) {
	var p *Parser = new(Parser)
	p.firstSectionContainingRule = -1
	p.lastSectionContainingRule = -1
	return p, p.getRules(node)
}

// getRules populates the rule slice by scanning HTML node and its children
func (p *Parser) getRules(node *html.Node) error {
	section, subSection, err := getSectionInfo(node)

	if err != nil {
		// skip this node and move on to its children
	} else {
		// Do not generate rules for introductory sections
		if section > 2 {
			// Check if this node is visited before. This is necessary since
			// sometimes to create rule description we visit siblings or children
			if marked := markedNodesSet[node]; marked {
				return nil
			}

			// update parser's section info
			if p.firstSectionContainingRule == -1 {
				p.firstSectionContainingRule = section
			}
			p.lastSectionContainingRule = section

			// extract rules from the node
			if err := p.getAlgorithmRule(node, section, subSection); err != nil {
				return err
			}
			if err := p.getNowrapRule(node, section, subSection); err != nil {
				return err
			}
			if err := p.getKeywordRule(node, section, subSection); err != nil {
				return err
			}
		}
	}

	for child := node.FirstChild; child != nil; child = child.NextSibling {
		if err := p.getRules(child); err != nil {
			return err
		}
	}
	return nil
}

// gatherKeywordRules scans the HTML node data, adds a new rules if it contains one
// of the keywords
func (p *Parser) getKeywordRule(node *html.Node, section int, subSection string) error {
	if node.Type != html.TextNode {
		return nil
	}

	hasKeyword, keyword := containsKeyword(node.Data, keywords)
	if !hasKeyword {
		return nil
	}

	// TODO(sarah): create a list of rule.sha1 for unwanted rules
	if strings.HasPrefix(node.Data, "/*") ||
		strings.Contains(node.Data, "reference must load and store from the same") ||
		strings.Contains(node.Data, " to an invalid reference may either: ") ||
		// Do not add Issues
		strings.Contains(node.Data, "Issue: ") ||
		strings.Contains(node.Data, "WebGPU issue") ||
		strings.Contains(node.Data, "/issues/") {
		return nil
	}

	id := getID(node)
	desc := cleanUpString(getNodeData(node))

	t, _, err := testName(id, desc, subSection)
	if err != nil {
		return err
	}

	sha, err := getSha1(desc, id)
	if err != nil {
		return err
	}

	r := rule{
		Sha:         sha,
		Number:      len(p.rules) + 1,
		Section:     section,
		SubSection:  subSection,
		URL:         headURL + "#" + id,
		Description: desc,
		TestName:    t,
		Keyword:     keyword,
	}
	p.rules = append(p.rules, r)

	return nil
}

// getNodeData builds the rule's description from the HTML node's data and all of its siblings.
// the node data is a usually a partial sentence, build the description from the node's data and
// all it's siblings to get a full context of the rule.
func getNodeData(node *html.Node) string {
	sb := strings.Builder{}
	if node.Parent != nil {
		for n := node.Parent.FirstChild; n != nil; n = n.NextSibling {
			printNodeText(n, &sb)
		}
	} else {
		printNodeText(node, &sb)
	}
	return sb.String()
}

// getAlgorithmRules scans the HTML node for blocks that
// contain an 'algorithm' class, populating the rule slice.
// i.e. <tr algorithm=...> and <p algorithm=...>
func (p *Parser) getAlgorithmRule(node *html.Node, section int, subSection string) error {
	if !hasClass(node, "algorithm") {
		return nil
	}
	// mark this node as seen
	markedNodesSet[node] = true

	sb := strings.Builder{}
	printNodeText(node, &sb)
	title := cleanUpStartEnd(getNodeAttrValue(node, "data-algorithm"))
	desc := title + ":\n" + cleanUpString(sb.String())
	id := getID(node)
	testName, _, err := testName(id, desc, subSection)
	if err != nil {
		return err
	}

	sha, err := getSha1(desc, id)
	if err != nil {
		return err
	}

	r := rule{
		Sha:         sha,
		Number:      len(p.rules) + 1,
		Section:     section,
		SubSection:  subSection,
		URL:         headURL + "#" + id,
		Description: desc,
		TestName:    testName,
		Keyword:     "ALGORITHM",
	}
	p.rules = append(p.rules, r)
	return nil
}

// getNowrapRules scans the HTML node for blocks that contain a
// 'nowrap' class , populating the rule slice.
// ie. <td class="nowrap">
// TODO(https://crbug.com/tint/1157)
// remove this when https://github.com/gpuweb/gpuweb/pull/2084 is closed
// and make sure Derivative built-in functions are added to the rules
func (p *Parser) getNowrapRule(node *html.Node, section int, subSection string) error {
	if !hasClass(node, "nowrap") {
		return nil
	}
	// mark this node as seen
	markedNodesSet[node] = true
	desc := cleanUpStartEnd(getNodeData(node))
	id := getID(node)

	t, _, err := testName(id, desc, subSection)
	if err != nil {
		return err
	}

	sha, err := getSha1(desc, id)
	if err != nil {
		return err
	}

	r := rule{
		Sha:         sha,
		Number:      len(p.rules) + 1,
		SubSection:  subSection,
		Section:     section,
		URL:         headURL + "#" + id,
		Description: desc,
		TestName:    t,
		Keyword:     "Nowrap",
	}
	p.rules = append(p.rules, r)

	return nil
}

// hasClass returns true if node is has the given "class" attribute.
func hasClass(node *html.Node, class string) bool {
	for _, attr := range node.Attr {
		if attr.Key == "class" {
			classes := strings.Split(attr.Val, " ")
			for _, c := range classes {
				if c == class {
					return true
				}
			}
		}
	}
	return false
}

// getSectionInfo returns the section this node belongs to
func getSectionInfo(node *html.Node) (int, string, error) {
	sub := getNodeAttrValue(node, "data-level")
	for p := node; sub == "" && p != nil; p = p.Parent {
		sub = getSiblingSectionInfo(p)
	}
	// when there is and ISSUE in HTML section cannot be set
	// use the previously set section
	if sub == "" && globalSection == "" {
		// for the section Abstract no section can be found
		// return -1 to skip this node
		return -1, "", fmt.Errorf("cannot get section info")
	}
	if sub == "" {
		sub = globalSection
	}
	globalSection = sub
	sectionDims, err := parseSection(sub)
	if len(sectionDims) > -1 {
		return sectionDims[0], sub, err
	}
	return -1, sub, err
}

// getSection return the section of this node's sibling
// iterates over all siblings and return the first one it can determine
func getSiblingSectionInfo(node *html.Node) string {
	for sp := node.PrevSibling; sp != nil; sp = sp.PrevSibling {
		section := getNodeAttrValue(sp, "data-level")
		if section != "" {
			return section
		}
	}
	return ""
}

// GetSiblingSectionInfo determines if the node's id refers to an example
func isExampleNode(node *html.Node) string {
	for sp := node.PrevSibling; sp != nil; sp = sp.PrevSibling {
		id := getNodeAttrValue(sp, "id")
		if id != "" && !strings.Contains(id, "example-") {
			return id
		}
	}
	return ""
}

// getID returns the id of the section this node belongs to
func getID(node *html.Node) string {
	id := getNodeAttrValue(node, "id")
	for p := node; id == "" && p != nil; p = p.Parent {
		id = isExampleNode(p)
	}
	return id
}

var (
	reCleanUpString       = regexp.MustCompile(`\n(\n|\s|\t)+|(\s|\t)+\n`)
	reSpacePlusTwo        = regexp.MustCompile(`\t|\s{2,}`)
	reBeginOrEndWithSpace = regexp.MustCompile(`^\s|\s$`)
	reIrregularWhiteSpace = regexp.MustCompile(`§.`)
)

// cleanUpString creates a string by removing  all extra spaces, newlines and tabs
// form input string 'in' and returns it
// This is done so that the uniqueID does not change because of a change in white spaces
//
// example in:
// ` float abs:
// T is f32 or vecN<f32>
// 		abs(e: T ) -> 	T
// 	  Returns the absolute value of e (e.g. e  with a positive sign bit). Component-wise when T is a vector.
//   (GLSLstd450Fabs)`
//
// example out:
// `float abs:
// T is f32 or vecN<f32> abs(e: T ) -> T Returns the absolute value of e (e.g. e with a positive sign bit). Component-wise when T is a vector. (GLSLstd450Fabs)`
func cleanUpString(in string) string {
	out := reCleanUpString.ReplaceAllString(in, " ")
	out = reSpacePlusTwo.ReplaceAllString(out, " ")
	//`§.` is not a valid character for a cts description
	// ie. this is invalid: g.test().desc(`§.`)
	out = reIrregularWhiteSpace.ReplaceAllString(out, "section ")
	out = reBeginOrEndWithSpace.ReplaceAllString(out, "")
	return out
}

var (
	reCleanUpStartEnd = regexp.MustCompile(`^\s+|\s+$|^\t+|\t+$|^\n+|\n+$`)
)

// cleanUpStartEnd creates a string by removing all extra spaces,
// newlines and tabs form the start and end of the input string.
// Example:
//	input: "\s\t\nHello\s\n\t\Bye\s\s\s\t\n\n\n"
//  output: "Hello\s\n\tBye"
//  input2: "\nbye\n\n"
//  output2: "\nbye"
func cleanUpStartEnd(in string) string {
	out := reCleanUpStartEnd.ReplaceAllString(in, "")
	return out
}

var (
	name         = "^[a-zA-Z0-9_]+$"
	reName       = regexp.MustCompile(`[^a-zA-Z0-9_]`)
	reUnderScore = regexp.MustCompile(`[_]+`)
	reDoNotBegin = regexp.MustCompile(`^[0-9_]+|[_]$`)
)

// testName creates a test name given a rule id (ie. section name), description and section
// returns for a builtin rule:
// 		testName:${section name} + "," + ${builtin name}
// 		builtinName: ${builtin name}
//		err: nil
// returns for a other rules:
//		testName: ${section name} + "_rule_ + " + ${string(counter)}
//		builtinName: ""
//		err: nil
// if it cannot create a unique name it returns "", "", err.
func testName(id string, desc string, section string) (testName, builtinName string, err error) {
	// regex for every thing other than letters and numbers
	if desc == "" || section == "" || id == "" {
		return "", "", fmt.Errorf("cannot generate test name")
	}
	// avoid any characters other than letters, numbers and underscore
	id = reName.ReplaceAllString(id, "_")
	// avoid underscore repeats
	id = reUnderScore.ReplaceAllString(id, "_")
	// test name must not start with underscore or a number
	// nor end with and underscore
	id = reDoNotBegin.ReplaceAllString(id, "")

	sectionX, err := parseSection(section)
	if err != nil {
		return "", "", err
	}

	builtinName = ""
	index := strings.Index(desc, ":")
	if strings.Contains(id, "builtin_functions") && index > -1 {
		builtinName = reName.ReplaceAllString(desc[:index], "_")
		builtinName = reDoNotBegin.ReplaceAllString(builtinName, "")
		builtinName = reUnderScore.ReplaceAllString(builtinName, "_")
		match, _ := regexp.MatchString(name, builtinName)
		if match {
			testName = id + "," + builtinName
			// in case there is more than one builtin functions
			// with the same name in one section:
			// "id,builtin", "id,builtin2", "id,builtin3", ...
			for i := 2; testNamesSet[testName]; i++ {
				testName = id + "," + builtinName + strconv.Itoa(i)
			}
			testNamesSet[testName] = true
			return testName, builtinName, nil
		}

	}

	if sectionX[0] == globalPrevSectionX {
		globalRuleCounter++
	} else {
		globalRuleCounter = 0
		globalPrevSectionX = sectionX[0]
	}
	testName = id + ",rule" + strconv.Itoa(globalRuleCounter)
	if testNamesSet[testName] {
		testName = "error-unable-to-generate-unique-file-name"
		return testName, "", fmt.Errorf("unable to generate unique test name\n" + desc)
	}
	testNamesSet[testName] = true
	return testName, "", nil
}

// printNodeText traverses node and its children, writing the Data of all TextNodes to sb.
func printNodeText(node *html.Node, sb *strings.Builder) {
	// mark this node as seen
	markedNodesSet[node] = true
	if node.Type == html.TextNode {
		sb.WriteString(node.Data)
	}

	for child := node.FirstChild; child != nil; child = child.NextSibling {
		printNodeText(child, sb)
	}
}

// getNodeAttrValue scans attributes of 'node' and returns the value of attribute 'key'
// or an empty string if 'node' doesn't have an attribute 'key'
func getNodeAttrValue(node *html.Node, key string) string {
	for _, attr := range node.Attr {
		if attr.Key == key {
			return attr.Val
		}
	}
	return ""
}

// getSha1 returns the first 8 byte of sha1(a+b)
func getSha1(a string, b string) (string, error) {
	sum := sha1.Sum([]byte(a + b))
	sha := fmt.Sprintf("%x", sum[0:8])
	if sha1sSet[sha] {
		return "", fmt.Errorf("sha1 is not unique")
	}
	sha1sSet[sha] = true
	return sha, nil
}

// getUnimplementedPlan generate the typescript code of a test plan for rules in sections[start, end]
// then it writes the generated test plans in the given 'path'
func getUnimplementedTestPlan(p Parser, path string) error {
	rules := p.rules
	start := p.firstSectionContainingRule
	end := p.lastSectionContainingRule
	validationPath := filepath.Join(path, "validation")
	if err := validationTestPlan(rules, validationPath, start, end); err != nil {
		return err
	}

	executionPath := filepath.Join(path, "execution", "builtin")
	if err := executionTestPlan(rules, executionPath); err != nil {
		return err
	}
	return nil
}

// getTestPlanFilePath returns a sort friendly path
// example: if we have 10 sections, and generate filenames naively, this will be the sorted result:
// 		section1.spec.ts -> section10.spec.ts -> section2.spec.ts -> ...
//	    if we make all the section numbers have the same number of digits, we will get:
// 		section01.spec.ts -> section02.spec.ts -> ... -> section10.spec.ts
func getTestPlanFilePath(path string, x, y, digits int) (string, error) {
	fileName := ""
	if y != -1 {
		// section16.01.spec.ts, ...
		sectionFmt := fmt.Sprintf("section%%d_%%.%dd.spec.ts", digits)
		fileName = fmt.Sprintf(sectionFmt, x, y)
	} else {
		// section01.spec.ts, ...
		sectionFmt := fmt.Sprintf("section%%.%dd.spec.ts", digits)
		fileName = fmt.Sprintf(sectionFmt, x)
	}
	return filepath.Join(path, fileName), nil

}

// validationTestPlan generates the typescript code of a test plan for rules in sections[start, end]
func validationTestPlan(rules []rule, path string, start int, end int) error {
	content := [][]string{}
	filePath := []string{}
	for section := 0; section <= end; section++ {
		sb := strings.Builder{}
		sectionStr := strconv.Itoa(section)
		testDescription := "`WGSL Section " + sectionStr + " Test Plan`"
		sb.WriteString(fmt.Sprintf(validationTestHeader, testDescription))
		content = append(content, []string{sb.String()})
		f, err := getTestPlanFilePath(path, section, -1, len(strconv.Itoa(end)))
		if err != nil {
			return nil
		}
		filePath = append(filePath, f)
	}

	for _, r := range rules {
		sectionDims, err := parseSection(r.SubSection)
		if err != nil || len(sectionDims) == 0 {
			return err
		}
		section := sectionDims[0]
		if section < start || section >= end {
			continue
		}
		content[section] = append(content[section], testPlan(r))
	}

	for i := start; i <= end; i++ {
		if len(content[i]) > 1 {
			if err := writeFile(filePath[i], strings.Join(content[i], "\n")); err != nil {
				return err
			}
		}
	}
	return nil

}

// executionTestPlan generates the typescript code of a test plan for rules in the given section
// the rules in section X.Y.* will be written to path/sectionX_Y.spec.ts
func executionTestPlan(rules []rule, path string) error {
	// TODO(SarahM) This generates execution tests for builtin function tests. Add other executions tests.
	section, err := getBuiltinSectionNum(rules)
	if err != nil {
		return err
	}

	content := [][]string{}
	filePath := []string{}

	start, end, err := getSectionRange(rules, []int{section})
	if err != nil || start == -1 || end == -1 {
		return err
	}
	for y := 0; y <= end; y++ {
		fileName, err := getTestPlanFilePath(path, section, y, len(strconv.Itoa(end)))
		if err != nil {
			return err
		}
		filePath = append(filePath, fileName)

		sb := strings.Builder{}
		testDescription := fmt.Sprintf("`WGSL section %v.%v execution test`", section, y)
		sb.WriteString(fmt.Sprintf(executionTestHeader, testDescription))
		content = append(content, []string{sb.String()})
	}

	for _, r := range rules {
		if r.Section != section || !isBuiltinFunctionRule(r) {
			continue
		}

		index := -1
		sectionDims, err := parseSection(r.SubSection)
		if err != nil || len(sectionDims) == 0 {
			return err
		}

		if len(sectionDims) == 1 {
			// section = x
			index = 0
		} else {
			// section = x.y(.z)*
			index = sectionDims[1]
		}

		if index < 0 && index >= len(content) {
			return fmt.Errorf("cannot append to content, index %v out of range 0..%v",
				index, len(content)-1)
		}
		content[index] = append(content[index], testPlan(r))
	}

	for i := start; i <= end; i++ {
		// Write the file if there is a test in there
		// compared with >1 because content has at least the test description
		if len(content[i]) > 1 {
			if err := writeFile(filePath[i], strings.Join(content[i], "\n")); err != nil {
				return err
			}
		}
	}
	return nil
}

func getBuiltinSectionNum(rules []rule) (int, error) {
	for _, r := range rules {
		if strings.Contains(r.URL, "builtin-functions") {
			return r.Section, nil
		}
	}
	return -1, fmt.Errorf("unable to find the built-in function section")
}

func isBuiltinFunctionRule(r rule) bool {
	_, builtinName, _ := testName(r.URL, r.Description, r.SubSection)
	return builtinName != "" || strings.Contains(r.URL, "builtin-functions")
}

func testPlan(r rule) string {
	sb := strings.Builder{}
	sb.WriteString(fmt.Sprintf(unImplementedTestTemplate, r.TestName, r.Sha, r.URL,
		"`\n"+r.Description+"\n"+howToContribute+"\n`"))

	return sb.String()
}

const (
	validationTestHeader = `export const description = %v;

import { makeTestGroup } from '../../../common/framework/test_group.js';

import { ShaderValidationTest } from './shader_validation_test.js';

export const g = makeTestGroup(ShaderValidationTest);
`
	executionTestHeader = `export const description = %v;

import { makeTestGroup } from '../../../../common/framework/test_group.js';
import { GPUTest } from '../../../gpu_test.js';

export const g = makeTestGroup(GPUTest);
`
	unImplementedTestTemplate = `g.test('%v')
  .uniqueId('%v')
  .specURL('%v')
  .desc(
    %v
  )
  .params(u => u.combine('placeHolder1', ['placeHolder2', 'placeHolder3']))
  .unimplemented();
`
	howToContribute = `
Please read the following guidelines before contributing:
https://github.com/gpuweb/cts/blob/main/docs/plan_autogen.md`
)
