// 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"
	"io/ioutil"
	"log"
	"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 := ioutil.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 = ioutil.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
}
