//go:build ignore

// Copyright 2023 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.

// generrordocs creates a Markdown file for each (compiler) error code
// and its associated documentation.
// Note: this program must be run in this directory.
//   go run generrordocs.go <dir>

//go:generate go run generrordocs.go errors_markdown

package main

import (
	"bytes"
	"fmt"
	"go/ast"
	"go/importer"
	"go/parser"
	"go/token"
	"log"
	"os"
	"path"
	"strings"
	"text/template"

	. "go/types"
)

func main() {
	if len(os.Args) != 2 {
		log.Fatal("missing argument: generrordocs <dir>")
	}
	outDir := os.Args[1]
	if err := os.MkdirAll(outDir, 0755); err != nil {
		log.Fatal("unable to create output directory: %s", err)
	}
	walkCodes(func(name string, vs *ast.ValueSpec) {
		// ignore unused errors
		if name == "_" {
			return
		}
		// Ensure that < are represented correctly when its included in code
		// blocks. The goldmark Markdown parser converts them to &amp;lt;
		// when not escaped. It is the only known string with this issue.
		desc := strings.ReplaceAll(vs.Doc.Text(), "<", `{{raw "<"}}`)
		e := struct {
			Name        string
			Description string
		}{
			Name:        name,
			Description: fmt.Sprintf("```\n%s```\n", desyc),
		}
		var buf bytes.Buffer
		err := template.Must(template.New("eachError").Parse(markdownTemplate)).Execute(&buf, e)
		if err != nil {
			log.Fatalf("template.Must: %s", err)
		}
		if err := os.WriteFile(path.Join(outDir, name+".md"), buf.Bytes(), 0660); err != nil {
			log.Fatalf("os.WriteFile: %s\n", err)
		}
	})
	log.Printf("output directory: %s\n", outDir)
}

func walkCodes(f func(string, *ast.ValueSpec)) {
	fset := token.NewFileSet()
	file, err := parser.ParseFile(fset, "codes.go", nil, parser.ParseComments)
	if err != nil {
		log.Fatalf("ParseFile failed: %s", err)
	}
	conf := Config{Importer: importer.Default()}
	info := &Info{
		Types: make(map[ast.Expr]TypeAndValue),
		Defs:  make(map[*ast.Ident]Object),
		Uses:  make(map[*ast.Ident]Object),
	}
	_, err = conf.Check("types", fset, []*ast.File{file}, info)
	if err != nil {
		log.Fatalf("Check failed: %s", err)
	}
	for _, decl := range file.Decls {
		decl, ok := decl.(*ast.GenDecl)
		if !ok || decl.Tok != token.CONST {
			continue
		}
		for _, spec := range decl.Specs {
			spec, ok := spec.(*ast.ValueSpec)
			if !ok || len(spec.Names) == 0 {
				continue
			}
			obj := info.ObjectOf(spec.Names[0])
			if named, ok := obj.Type().(*Named); ok && named.Obj().Name() == "Code" {
				if len(spec.Names) != 1 {
					log.Fatalf("bad Code declaration for %q: got %d names, want exactly 1", spec.Names[0].Name, len(spec.Names))
				}
				codename := spec.Names[0].Name
				f(codename, spec)
			}
		}
	}
}

const markdownTemplate = `---
title: {{.Name}}
layout: article
---
<!-- Copyright 2023 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. -->

<!-- Code generated by generrordocs.go; DO NOT EDIT. -->

{{.Description}}
`
