// Copyright 2020 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 fuzz

import (
	"flag"
	"fmt"
	"io"
	"os"

	"github.com/golang/glog"
)

// API version
const (
	VersionMajor = 0
	VersionMinor = 1
	VersionPatch = 0
)

// Available subcommand names
const (
	StartInstance = "start_instance"
	StopInstance  = "stop_instance"
	ListFuzzers   = "list_fuzzers"
	PrepareFuzzer = "prepare_fuzzer"
	GetLogs       = "get_logs"
	RunFuzzer     = "run_fuzzer"
	GetData       = "get_data"
	PutData       = "put_data"
	Version       = "version"
)

var commandDesc = map[string]string{
	StartInstance: "Start a Fuchsia instance",
	StopInstance:  "Stop a Fuchsia instance",
	ListFuzzers:   "List available fuzz targets on an instance",
	PrepareFuzzer: "Prepare a fuzzer to be run",
	GetLogs:       "Get debug logs from an instance",
	RunFuzzer:     "Run a fuzz target on an instance (passing any extra args to libFuzzer)",
	GetData:       "Copy files between an instance and a local path",
	PutData:       "Copy files between a local path and an instance",
	Version:       "Get API version",
}

// An APICommand is the structured result of parsing the command-line args
type APICommand struct {
	name string

	handle  string
	fuzzer  string
	srcPath string
	dstPath string

	extraArgs []string
}

// Execute the APICommand, writing any output to the given io.Writer
func (c *APICommand) Execute(out io.Writer) error {
	var instance Instance

	glog.Infof("Running API command: %v\n", c)

	// For commands that take a handle, load the Instance from the handle
	if c.handle != "" {
		handle, err := LoadHandleFromString(c.handle)
		if err != nil {
			return fmt.Errorf("Bad handle: %s", err)
		}

		if instance, err = loadInstanceFromHandle(handle); err != nil {
			return fmt.Errorf("Bad handle: %s", err)
		}
		defer instance.Close()
	}

	switch c.name {
	case StartInstance:
		instance, err := NewInstance()
		if err != nil {
			return fmt.Errorf("Error creating instance: %s", err)
		}

		glog.Info("Starting instance...")
		if err := instance.Start(); err != nil {
			return fmt.Errorf("Error starting instance: %s", err)
		}
		glog.Info("Instance started.")
		defer instance.Close()

		handle, err := instance.Handle()
		if err != nil {
			return fmt.Errorf("Error getting instance handle: %s", err)
		}
		fmt.Fprintf(out, "%s\n", handle.Serialize())
	case StopInstance:
		return instance.Stop()
	case ListFuzzers:
		for _, name := range instance.ListFuzzers() {
			fmt.Fprintf(out, "%s\n", name)
		}
	case PrepareFuzzer:
		return instance.PrepareFuzzer(c.fuzzer)
	case GetLogs:
		return instance.GetLogs(out)
	case GetData:
		return instance.Get(c.fuzzer, c.srcPath, c.dstPath)
	case PutData:
		return instance.Put(c.fuzzer, c.srcPath, c.dstPath)
	case RunFuzzer:
		// TODO(fxbug.dev/45431): buffer output so we don't get prematurely terminated by CF
		return instance.RunFuzzer(out, c.fuzzer, c.dstPath, c.extraArgs...)
	case Version:
		fmt.Fprintf(out, "v%d.%d.%d\n", VersionMajor, VersionMinor, VersionPatch)
	}
	return nil
}

// ParseArgs converts command-line args into an API-command
func ParseArgs(args []string) (*APICommand, error) {
	if len(args) == 0 {
		printUsage()
		return nil, fmt.Errorf("missing subcommand")
	}

	cmd := &APICommand{name: args[0]}

	flagSet := flag.NewFlagSet(cmd.name, flag.ContinueOnError)
	handleDesc := fmt.Sprintf("an instance `handle`, as returned by %s", StartInstance)
	fuzzerDesc := fmt.Sprintf("a `fuzzer` name, as returned by %s", ListFuzzers)

	var requiredArgs []*string

	switch cmd.name {
	case StartInstance, Version:
	case StopInstance, ListFuzzers, GetLogs:
		flagSet.StringVar(&cmd.handle, "handle", "", handleDesc)
		requiredArgs = []*string{&cmd.handle}
	case PrepareFuzzer:
		flagSet.StringVar(&cmd.handle, "handle", "", handleDesc)
		flagSet.StringVar(&cmd.fuzzer, "fuzzer", "", fuzzerDesc)
		requiredArgs = []*string{&cmd.handle, &cmd.fuzzer}
	case RunFuzzer:
		flagSet.StringVar(&cmd.handle, "handle", "", handleDesc)
		flagSet.StringVar(&cmd.fuzzer, "fuzzer", "", fuzzerDesc)
		flagSet.StringVar(&cmd.dstPath, "artifact-dir", "", "host `path` to store artifacts")
		requiredArgs = []*string{&cmd.handle, &cmd.fuzzer}
	case GetData:
		flagSet.StringVar(&cmd.handle, "handle", "", handleDesc)
		flagSet.StringVar(&cmd.fuzzer, "fuzzer", "", fuzzerDesc)
		flagSet.StringVar(&cmd.srcPath, "src", "", "target source `path` (may include glob)")
		flagSet.StringVar(&cmd.dstPath, "dst", "", "host destination `path`")
		requiredArgs = []*string{&cmd.handle, &cmd.fuzzer, &cmd.srcPath, &cmd.dstPath}
	case PutData:
		flagSet.StringVar(&cmd.handle, "handle", "", handleDesc)
		flagSet.StringVar(&cmd.fuzzer, "fuzzer", "", fuzzerDesc)
		flagSet.StringVar(&cmd.srcPath, "src", "", "host source `path` (may include glob)")
		flagSet.StringVar(&cmd.dstPath, "dst", "", "target destination `path`")
		requiredArgs = []*string{&cmd.handle, &cmd.fuzzer, &cmd.srcPath, &cmd.dstPath}
	default:
		printUsage()
		return nil, fmt.Errorf("unknown subcommand: %s", cmd.name)
	}

	if err := flagSet.Parse(args[1:]); err != nil {
		// Usage will already have been printed by Parse() in this case
		return nil, err
	}

	// Handle missing arguments
	for _, arg := range requiredArgs {
		if *arg == "" {
			flagSet.Usage()
			return nil, fmt.Errorf("not enough arguments")
		}
	}

	// Handle any extra args
	if flagSet.NArg() > 0 {
		if cmd.name == RunFuzzer {
			cmd.extraArgs = flagSet.Args()
		} else {
			flagSet.Usage()
			return nil, fmt.Errorf("too many arguments")
		}
	}

	return cmd, nil
}

func printUsage() {
	fmt.Printf("Usage: %s <subcommand>\n\n", os.Args[0])
	fmt.Printf("Supported subcommands:\n")
	for name, desc := range commandDesc {
		fmt.Printf(" - %s: %s\n", name, desc)
	}
}
