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

// +build ignore

package main

import (
	"bytes"
	"flag"
	exec "internal/execabs"
	"log"
	"os"
	"strings"
	"testing"
	"text/template"
)

func main() {
	if err := regenerate(); err != nil {
		log.Fatal(err)
	}
}

func regenerate() error {
	t := template.Must(template.New("fileTemplate").Parse(fileTemplate))
	buf := bytes.NewBuffer(nil)
	if err := t.Execute(buf, testFlags()); err != nil {
		return err
	}

	f, err := os.Create("flagdefs.go")
	if err != nil {
		return err
	}

	cmd := exec.Command("gofmt")
	cmd.Stdin = buf
	cmd.Stdout = f
	cmd.Stderr = os.Stderr
	cmdErr := cmd.Run()

	if err := f.Close(); err != nil {
		return err
	}
	if cmdErr != nil {
		os.Remove(f.Name())
		return cmdErr
	}

	return nil
}

func testFlags() []string {
	testing.Init()

	var names []string
	flag.VisitAll(func(f *flag.Flag) {
		if !strings.HasPrefix(f.Name, "test.") {
			return
		}
		name := strings.TrimPrefix(f.Name, "test.")

		if name == "testlogfile" {
			// test.testlogfile is “for use only by cmd/go”
		} else {
			names = append(names, name)
		}
	})

	return names
}

const fileTemplate = `// Copyright 2019 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 genflags.go — DO NOT EDIT.

package test

// passFlagToTest contains the flags that should be forwarded to
// the test binary with the prefix "test.".
var passFlagToTest = map[string]bool {
{{- range .}}
	"{{.}}": true,
{{- end }}
}
`
