// 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)
		}

		// stop_instance should make its best effort even with an incomplete
		// handle, as long as it contains enough information
		verify := c.name != StopInstance
		if instance, err = loadInstanceFromHandle(handle, verify); 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(https://fxbug.dev/42121955): 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)
	}
}
