// The star2proto command executes a Starlark file and prints a protocol
// message, which it expects to find in a module-level variable named 'result'.
//
// THIS COMMAND IS EXPERIMENTAL AND ITS INTERFACE MAY CHANGE.
package main

// TODO(adonovan): add features to make this a useful tool for querying,
// converting, and building messages in proto, JSON, and YAML.
// - define operations for reading and writing files.
// - support (e.g.) querying a proto file given a '-e expr' flag.
//   This will need a convenient way to put the relevant descriptors in scope.

import (
	"flag"
	"fmt"
	"io/ioutil"
	"log"
	"os"
	"strings"

	starlarkproto "go.starlark.net/lib/proto"
	"go.starlark.net/resolve"
	"go.starlark.net/starlark"
	"go.starlark.net/starlarkjson"
	"google.golang.org/protobuf/encoding/protojson"
	"google.golang.org/protobuf/encoding/prototext"
	"google.golang.org/protobuf/proto"
	"google.golang.org/protobuf/reflect/protodesc"
	"google.golang.org/protobuf/reflect/protoreflect"
	"google.golang.org/protobuf/reflect/protoregistry"
	"google.golang.org/protobuf/types/descriptorpb"
)

// flags
var (
	outputFlag  = flag.String("output", "text", "output format (text, wire, json)")
	varFlag     = flag.String("var", "result", "the variable to output")
	descriptors = flag.String("descriptors", "", "comma-separated list of names of files containing proto.FileDescriptorProto messages")
)

// Starlark dialect flags
func init() {
	flag.BoolVar(&resolve.AllowFloat, "fp", true, "allow floating-point numbers")
	flag.BoolVar(&resolve.AllowSet, "set", resolve.AllowSet, "allow set data type")
	flag.BoolVar(&resolve.AllowLambda, "lambda", resolve.AllowLambda, "allow lambda expressions")
	flag.BoolVar(&resolve.AllowNestedDef, "nesteddef", resolve.AllowNestedDef, "allow nested def statements")
}

func main() {
	log.SetPrefix("star2proto: ")
	log.SetFlags(0)
	flag.Parse()
	if len(flag.Args()) != 1 {
		fatalf("requires a single Starlark file name")
	}
	filename := flag.Args()[0]

	// By default, use the linked-in descriptors
	// (very few in star2proto, e.g. descriptorpb itself).
	pool := protoregistry.GlobalFiles

	// Load a user-provided FileDescriptorSet produced by a command such as:
	// $ protoc --descriptor_set_out=foo.fds foo.proto
	if *descriptors != "" {
		var fdset descriptorpb.FileDescriptorSet
		for i, filename := range strings.Split(*descriptors, ",") {
			data, err := ioutil.ReadFile(filename)
			if err != nil {
				log.Fatalf("--descriptors[%d]: %s", i, err)
			}
			// Accumulate into the repeated field of FileDescriptors.
			if err := (proto.UnmarshalOptions{Merge: true}).Unmarshal(data, &fdset); err != nil {
				log.Fatalf("%s does not contain a proto2.FileDescriptorSet: %v", filename, err)
			}
		}

		files, err := protodesc.NewFiles(&fdset)
		if err != nil {
			log.Fatalf("protodesc.NewFiles: could not build FileDescriptor index: %v", err)
		}
		pool = files
	}

	// Execute the Starlark file.
	thread := &starlark.Thread{
		Print: func(_ *starlark.Thread, msg string) { fmt.Println(msg) },
	}
	starlarkproto.SetPool(thread, pool)
	predeclared := starlark.StringDict{
		"proto": starlarkproto.Module,
		"json":  starlarkjson.Module,
	}
	globals, err := starlark.ExecFile(thread, filename, nil, predeclared)
	if err != nil {
		if evalErr, ok := err.(*starlark.EvalError); ok {
			fatalf("%s", evalErr.Backtrace())
		} else {
			fatalf("%s", err)
		}
	}

	// Print the output variable as a message.
	// TODO(adonovan): this is clumsy.
	// Let the user call print(), or provide an expression on the command line.
	result, ok := globals[*varFlag]
	if !ok {
		fatalf("%s must define a module-level variable named %q", filename, *varFlag)
	}
	msgwrap, ok := result.(*starlarkproto.Message)
	if !ok {
		fatalf("got %s, want proto.Message, for %q", result.Type(), *varFlag)
	}
	msg := msgwrap.Message()

	// -output
	var marshal func(protoreflect.ProtoMessage) ([]byte, error)
	switch *outputFlag {
	case "wire":
		marshal = proto.Marshal

	case "text":
		marshal = prototext.MarshalOptions{Multiline: true, Indent: "\t"}.Marshal

	case "json":
		marshal = protojson.MarshalOptions{Multiline: true, Indent: "\t"}.Marshal

	default:
		fatalf("unsupported -output format: %s", *outputFlag)
	}
	data, err := marshal(msg)
	if err != nil {
		fatalf("%s", err)
	}
	os.Stdout.Write(data)
}

func fatalf(format string, args ...interface{}) {
	fmt.Fprintf(os.Stderr, "star2proto: ")
	fmt.Fprintf(os.Stderr, format, args...)
	fmt.Fprintln(os.Stderr)
	os.Exit(1)
}
