// Copyright 2016 The Vanadium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// The following enables go generate to generate the doc.go file.
//go:generate go run $JIRI_ROOT/release/go/src/v.io/x/lib/cmdline/testdata/gendoc.go . -help

package main

import (
	"fmt"
	"io"
	"os"
	"strings"

	"v.io/v23/vdl"
	"v.io/v23/vdl/vdltest"
	"v.io/x/lib/cmdline"
	"v.io/x/lib/textutil"
	"v.io/x/ref/lib/vdl/build"
	"v.io/x/ref/lib/vdl/codegen/vdlgen"
	"v.io/x/ref/lib/vdl/compile"
)

var cmdGen = &cmdline.Command{
	Runner: cmdline.RunnerFunc(runGen),
	Name:   "vdltestgen",
	Short:  "generates test data for the vdltest package",
	Long: `
Command vdltestgen generates types and values for the vdltest package.  The
following files are generated:

   vtype_gen.vdl       - Named "V" types, regular VDL types.
   ventry_pass_gen.vdl - Entries that pass conversion from source to target.
   ventry_fail_gen.vdl - Entries that fail conversion from source to target.

   xtype_gen.vdl       - Named "X" types, no VDL{IsZero,Read,Write} methods.
   xentry_pass_gen.vdl - Entries that pass conversion from source to target.
   xentry_fail_gen.vdl - Entries that fail conversion from source to target.

Do not run this tool manually.  Instead invoke it via:
   $ jiri run go generate v.io/v23/vdl/vdltest
`,
}

func main() {
	cmdline.Main(cmdGen)
}

const (
	vdltestPkgName     = "v.io/v23/vdl/vdltest"
	typeGenFileName    = "type_gen.vdl"
	typeManualFileName = "type_manual.vdl"
	passGenFileName    = "entry_pass_gen.vdl"
	failGenFileName    = "entry_fail_gen.vdl"
)

func runGen(_ *cmdline.Env, _ []string) error {
	// Build the vdltest package, to pick up manually-generated types and entries.
	vdltestPkg, err := buildVDLTestPackage()
	if err != nil {
		return err
	}
	// Generate "v" types and entries.
	vGenTypes := genAndWriteTypes("v")
	vManTypes := collectManualTypes("v", vdltestPkg)
	vPass, vFail := genEntries(vGenTypes, vGenTypes)
	pass, fail := genEntries(vManTypes, append(vManTypes, vGenTypes...))
	writeEntries("v", append(vPass, pass...), append(vFail, fail...))
	// Generate "x" types and entries, skipping entries already covered by "v".
	xGenTypes := genAndWriteTypes("x")
	xManTypes := collectManualTypes("x", vdltestPkg)
	xTargetTypes := subtractTypes(xGenTypes, vGenTypes)
	xPass, xFail := genEntries(xTargetTypes, xGenTypes)
	pass, fail = genEntries(xManTypes, append(xManTypes, xGenTypes...))
	writeEntries("x", append(xPass, pass...), append(xFail, fail...))
	return nil
}

func buildVDLTestPackage() (*compile.Package, error) {
	env := compile.NewEnv(-1)
	pkgs := build.TransitivePackages([]string{vdltestPkgName}, build.UnknownPathIsError, build.Opts{}, env.Errors)
	if !env.Errors.IsEmpty() {
		return nil, env.Errors.ToError()
	}
	for _, pkg := range pkgs {
		build.BuildPackage(pkg, env)
	}
	return env.ResolvePackage(vdltestPkgName), env.Errors.ToError()
}

// genAndWriteTypes generates types and writes the type file.
func genAndWriteTypes(prefix string) []*vdl.Type {
	const maxTypeDepth = 3
	gen := vdltest.NewTypeGenerator()
	gen.RandSeed(1)
	gen.NamePrefix = strings.ToUpper(prefix)
	genTypes := gen.Gen(maxTypeDepth)
	writeTypeFile(prefix+typeGenFileName, genTypes)
	return genTypes
}

// collectManualTypes collects manually-defined types from pkg.
func collectManualTypes(prefix string, pkg *compile.Package) []*vdl.Type {
	var manTypes []*vdl.Type
	for _, file := range pkg.Files {
		if file.BaseName != prefix+typeManualFileName {
			continue
		}
		for _, def := range file.TypeDefs {
			manTypes = append(manTypes, def.Type)
		}
	}
	return manTypes
}

// subtractTypes returns all types that don't appear in sub.
func subtractTypes(types, sub []*vdl.Type) []*vdl.Type {
	subMap := make(map[*vdl.Type]bool)
	for _, tt := range sub {
		subMap[tt] = true
	}
	var result []*vdl.Type
	for _, tt := range types {
		if !subMap[tt] {
			result = append(result, tt)
		}
	}
	return result
}

// genEntries generates entries for all target types, using source types as the
// candidates to mimic conversion values.
func genEntries(target, source []*vdl.Type) (pass, fail []vdltest.EntryValue) {
	gen := vdltest.NewEntryGenerator(source)
	gen.RandSeed(1)
	pass = gen.GenAllPass(target)
	gen.RandSeed(1)
	fail = gen.GenAllFail(target)
	return
}

func writeEntries(prefix string, pass, fail []vdltest.EntryValue) {
	writeEntryFile(prefix+passGenFileName, prefix+"AllPass", pass)
	writeEntryFile(prefix+failGenFileName, prefix+"AllFail", fail)
}

// This tool is only used to generate test cases for the vdltest package, so the
// strategy is to panic on any error, to make the code simpler.
func panicOnError(err error) {
	if err != nil {
		panic(err)
	}
}

func createFile(name string) (*os.File, func()) {
	file, err := os.Create(name)
	panicOnError(err)
	return file, func() { panicOnError(file.Close()) }
}

func writef(w io.Writer, format string, args ...interface{}) {
	_, err := fmt.Fprintf(w, format, args...)
	panicOnError(err)
}

func writeHeader(w io.Writer) {
	writef(w, `// Copyright 2016 The Vanadium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// This file was auto-generated by v.io/v23/vdl/vdltest/internal/vdltestgen
// Run the following to re-generate:
//   $ jiri run go generate v.io/v23/vdl/vdltest

package vdltest

`)
}

func writeTypeFile(fileName string, types []*vdl.Type) {
	fmt.Printf("Writing %[1]s:\t%[2]d types\n", fileName, len(types))
	file, cleanup := createFile(fileName)
	defer cleanup()
	writeHeader(file)
	comment := textutil.PrefixLineWriter(file, "// ")
	panicOnError(vdltest.PrintTypeStats(comment, types...))
	writef(comment, "\nOnly named types appear below, by definition.\n")
	panicOnError(comment.Flush())
	writef(file, "\ntype (\n")
	for _, tt := range types {
		if tt.Name() != "" {
			base := vdlgen.BaseType(tt, vdltestPkgName, nil)
			base = strings.Replace(base, "\n", "\n\t", -1)
			writef(file, "\t%[1]s %[2]s\n", tt.Name(), base)
		}
	}
	writef(file, ")\n")
}

func writeEntryFile(fileName, constName string, entries []vdltest.EntryValue) {
	fmt.Printf("Writing %[1]s:\t%[2]d entries\n", fileName, len(entries))
	file, cleanup := createFile(fileName)
	defer cleanup()
	writeHeader(file)
	comment := textutil.PrefixLineWriter(file, "// ")
	panicOnError(vdltest.PrintEntryStats(comment, entries...))
	panicOnError(comment.Flush())
	writef(file, "\nconst %[1]s = []vdlEntry{\n", constName)
	for _, e := range entries {
		if e.IsCanonical() {
			writef(file, "\t// Canonical\n")
		}
		target := vdlgen.TypedConst(e.Target, vdltestPkgName, nil)
		source := vdlgen.TypedConst(e.Source, vdltestPkgName, nil)
		if len(target)*2+len(source)*2 < 100 {
			// Write a pretty one-liner, if it's short enough.
			writef(file, "\t{ %[1]v, %#[2]q, %#[3]q, %[3]s, %#[4]q, %[4]s },\n", e.IsCanonical(), e.Label, target, source)
		} else {
			writef(file, "\t{ %[1]v, %#[2]q,\n\t  %#[3]q,\n\t  %[3]s,\n\t  %#[4]q,\n\t  %[4]s,\n\t},\n", e.IsCanonical(), e.Label, target, source)
		}
	}
	writef(file, "}\n")
}
