// Copyright 2021 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 file generates exceptions.gen.go.
// It embeds the text of all the license LREs in the subdirectory "exceptions"
// and constructs the data structures to represent them.
// Run by a "go:generate" comment in licenses.go.

// Modified from github.com/google/licensecheck/gen_data.go.

package main

import (
	"bytes"
	"flag"
	"fmt"
	"go/format"
	"log"
	"os"
	"path/filepath"
	"sort"
	"strings"
	"text/template"

	"github.com/google/licensecheck"
)

func main() {
	log.SetFlags(0)
	log.SetPrefix("gen: ")
	flag.Parse()

	filesLRE, err := filepath.Glob(filepath.Join("exceptions", "*.lre"))
	if err != nil {
		log.Fatal(err)
	}
	if len(filesLRE) == 0 {
		log.Fatal("no license files")
	}

	code := outputTemplate
	out := new(bytes.Buffer)
	builtLRE := buildLRE(filesLRE)
	for _, file := range builtLRE {
		fmt.Fprintf(out, "\t\t{ID: %q, %s LRE: %v},\n", file.Name, file.Type, varName(file.Name+".lre"))
	}
	code = strings.Replace(code, "FILES_LIST", out.String(), -1)

	out.Reset()
	for _, file := range builtLRE {
		if len(file.Types) == 0 {
			continue
		}
		var ss []string
		for _, t := range file.Types {
			ss = append(ss, fmt.Sprintf("%q", t))
		}
		fmt.Fprintf(out, "\t\t%q: {%s},\n", file.Name, strings.Join(ss, ", "))
	}
	code = strings.Replace(code, "TYPES_LIST", out.String(), -1)

	out.Reset()
	for _, file := range builtLRE {
		fmt.Fprintf(out, "const %s = `%s`\n",
			varName(file.Name+".lre"),
			bytes.ReplaceAll(file.Data, []byte("`"), []byte("` + \"`\" + `")))
	}
	code += out.String()

	src, err := format.Source([]byte(code))
	if err != nil {
		fd, err1 := io.TempFile("", "license-data")
		if err1 == nil {
			_, err1 = fd.Write([]byte(code))
			if err1 == nil {
				log.Fatalf("parsing output (written to %s): %v", fd.Name(), err)
			}
			fd.Close()
		}
		log.Fatal("parsing output:", err)
	}
	err = os.WriteFile("exceptions.gen.go", src, 0644)
	if err != nil {
		log.Fatal(err)
	}
}

// varName returns the basename of the file, sanitized for use as a variable name,
// and given the prefix "license_".
func varName(file string) string {
	mapping := func(r rune) rune {
		if r == '-' || r == '.' || r == '+' {
			return '_'
		}
		return r
	}
	return "license_" + strings.Map(mapping, filepath.Base(file))
}

const outputTemplate = `
// Copyright 2021 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 gen_exceptions.go; DO NOT EDIT.

//lint:file-ignore ST1018 Ignore staticcheck message about Unicode control characters.

package licenses

import "github.com/google/licensecheck"

var exceptionLicenses = []licensecheck.License{
	FILES_LIST
}

var exceptionTypes = map[string][]string{
	TYPES_LIST
}
`

type fileData struct {
	Name  string
	Type  string   // licensecheck Type, not used
	Types []string // reported types
	Data  []byte
}

func buildLRE(filesLRE []string) []fileData {

	// setType obtains a licensecheck.Type from the template.
	// This is a bitset of license properties. Neither the licensecheck package
	// nor this package uses it.
	var typ licensecheck.Type
	setType := func(s string) (string, error) {
		t, err := licensecheck.ParseType(s)
		if err != nil {
			return "", err
		}
		typ = t
		return "", nil
	}

	// setTypes sets the reported license types for this package.
	var types []string
	setTypes := func(s string) string {
		types = strings.Fields(s)
		return ""
	}

	var out []fileData
	t := template.New("").Funcs(template.FuncMap{
		"list":  templateList,
		"Type":  setType,
		"Types": setTypes,
	})
	t, err := t.ParseFiles(filesLRE...)
	if err != nil {
		log.Fatal("parsing LRE templates:", err)
	}
	for _, t := range t.Templates() {
		if strings.HasSuffix(t.Name(), ".lre") {
			var buf bytes.Buffer
			typ = licensecheck.Unknown
			types = nil
			if err := t.Execute(&buf, nil); err != nil {
				log.Fatalf("executing %s: %v", t.Name(), err)
			}
			if len(bytes.TrimSpace(buf.Bytes())) == 0 {
				// Only contained useful definitions.
				continue
			}
			tstr := ""
			if typ != licensecheck.Unknown {
				tstr = "Type: " + typ.String() + ","
			}
			out = append(out, fileData{strings.TrimSuffix(t.Name(), ".lre"), tstr, types, buf.Bytes()})
		}
	}
	sort.Slice(out, func(i, j int) bool {
		ni, nj := out[i].Name, out[j].Name

		// Special case: BSD-4-Clause is a generalization of BSD-4-Clause-UC.
		// In case of multiple matches, licensecheck always returns the one earlier in the list.
		// Make BSD-4-Clause-UC the one earlier in the list.
		if strings.HasPrefix(ni, "BSD-4-Clause") && strings.HasPrefix(nj, "BSD-4-Clause") {
			ni, nj = nj, ni
		}

		// Special case: GFDL-1.[123]-invariants-* is a generalization of GFDL-1.[123]-no-invariants-*.
		// Reverse that order too.
		if strings.HasPrefix(ni, "GFDL-") && strings.HasPrefix(nj, "GFDL-") {
			ni, nj = nj, ni
		}

		return ni < nj
	})

	return out
}

// templateList returns xs, but it flattens any nested []interface{} into the main list.
// Called from templates as "list", to pass multiple arguments to templates.
func templateList(xs ...interface{}) []interface{} {
	var list []interface{}
	for _, x := range xs {
		switch x := x.(type) {
		case []interface{}:
			list = append(list, x...)
		default:
			list = append(list, x)
		}
	}
	return list
}
