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

package main

import (
	"encoding/json"
	"flag"
	"fmt"
	"log"
	"os"
	"strings"
)

type Options map[string]string

func (o *Options) String() string {
	return fmt.Sprintf("%v", *o)
}

func (o *Options) Set(args string) error {
	for _, option := range strings.Split(args, ",") {
		nameValue := strings.Split(option, "=")
		(*o)[nameValue[0]] = nameValue[1]
	}
	return nil
}

type Flags struct {
	jsonPath     *string
	amendPath    *string
	templatePath *string
	outputBase   *string
}

// GetFlags returns the set of flags.
func GetFlags() Flags {
	return Flags{
		flag.String("json", "",
			"relative path to the FIDL intermediate representation."),
		flag.String("amend", "",
			"relative path to FIDL amendments file."),
		flag.String("template", "",
			"relative path to the template."),
		flag.String("output-base", "",
			"the base file name for files generated by this generator."),
	}
}

// Valid returns true if the parsed flags are valid.
func (f Flags) Valid() bool {
	return *f.jsonPath != "" && *f.templatePath != "" && *f.outputBase != ""
}

// FidlAmendments returns the Amendments read from the JSON amend file specified as an argument.
func (f Flags) FidlAmendments() Amendments {
	var amendments Amendments

	if *f.amendPath == "" {
		return amendments
	}

	bytes, err := os.ReadFile(*f.amendPath)
	if err != nil {
		log.Fatalf("Error reading from %s: %v", *f.amendPath, err)
	}

	err = json.Unmarshal(bytes, &amendments)
	if err != nil {
		log.Fatalf("Error parsing JSON as FIDL amendment data: %v", err)
	}

	return amendments
}
