// 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 lib

import (
	"bufio"
	"fmt"
	"io"
	"regexp"
	"strconv"
	"strings"

	"github.com/golang/glog"
)

// A Fuzzer represents a fuzzer present on an instance.
type Fuzzer struct {
	build Build
	// Name is `package/binary`
	Name string

	pkg     string
	cmx     string
	url     string
	args    []string
	options map[string]string
}

var expectedFuzzerReturnCodes = [...]int{0, 1, 77}

// NewFuzzer constructs a fuzzer object with the given pkg/fuzzer name
func NewFuzzer(build Build, pkg, fuzzer string) *Fuzzer {
	return &Fuzzer{
		build: build,
		Name:  fmt.Sprintf("%s/%s", pkg, fuzzer),
		pkg:   pkg,
		cmx:   fmt.Sprintf("%s.cmx", fuzzer),
		url:   fmt.Sprintf("fuchsia-pkg://fuchsia.com/%s#meta/%s.cmx", pkg, fuzzer),
	}
}

// AbsPath returns the absolute target path for a given relative path in a
// fuzzer package. The path may differ depending on whether it is identified as
// a resource, data, or neither.
func (f *Fuzzer) AbsPath(relpath string) string {
	if strings.HasPrefix(relpath, "/") {
		return relpath
	} else if strings.HasPrefix(relpath, "pkg/") {
		return fmt.Sprintf("/pkgfs/packages/%s/0/%s", f.pkg, relpath[4:])
	} else if strings.HasPrefix(relpath, "data/") {
		return fmt.Sprintf("/data/r/sys/fuchsia.com:%s:0#meta:%s/%s", f.pkg, f.cmx, relpath[5:])
	} else {
		return fmt.Sprintf("/%s", relpath)
	}
}

// Parse command line arguments for the fuzzer. For '-key=val' style options,
// the last 'val' for a given 'key' is used.
func (f *Fuzzer) Parse(args []string) {
	f.options = make(map[string]string)
	re := regexp.MustCompile(`^-([^-=\s]*)=([^-=\s]*)$`)
	for _, arg := range args {
		submatch := re.FindStringSubmatch(arg)
		if submatch == nil {
			f.args = append(f.args, arg)
		} else {
			f.options[submatch[1]] = submatch[2]
		}
	}
}

func scanFuzzerOutput(conn Connector, out io.WriteCloser, in io.Reader) (chan error,
	chan []string) {

	scanErr := make(chan error, 1)
	artifactsCh := make(chan []string, 1)

	go func() {
		defer out.Close() // Propagate the EOF, so the symbolizer terminates properly

		artifacts := []string{}

		// mutRegex detects output from
		// MutationDispatcher::PrintMutationSequence
		// (compiler-rt/lib/fuzzer/FuzzerMutate.cpp), which itself is called
		// from Fuzzer::DumpCurrentUnit (compiler-rt/lib/fuzzer/FuzzerLoop.cpp)
		// as part of exit/crash callbacks
		mutRegex := regexp.MustCompile(`^MS: [0-9]*`)
		pidRegex := regexp.MustCompile(`^==([0-9]+)==`)
		artifactRegex := regexp.MustCompile(`Test unit written to (\S*)`)
		sawMut := false
		sawPid := false
		scanner := bufio.NewScanner(in)
		pid := 0
		for scanner.Scan() {
			line := scanner.Text()
			if m := pidRegex.FindStringSubmatch(line); m != nil {
				if sawPid {
					glog.Warningf("Saw multiple PIDs")
				}
				sawPid = true

				pid, _ = strconv.Atoi(m[1]) // guaranteed parseable due to regex
				glog.Infof("Found fuzzer PID: %d", pid)
			}
			if m := artifactRegex.FindStringSubmatch(line); m != nil {
				glog.Infof("Found artifact: %s", m[1])
				artifacts = append(artifacts, m[1])
			}
			if mutRegex.MatchString(line) {
				if sawMut {
					glog.Warningf("Saw multiple mutation sequences")
				}
				sawMut = true

				glog.Infof("Found mutation sequence: %s", line)
				if pid == 0 {
					glog.Warningf("WARNING: failed to fetch syslog: missing pid")
					// Include this warning inline so it is visible in fuzzer logs
					fmt.Fprintf(out, "WARNING: failed to fetch syslog: missing pid\n")
				} else {
					log, err := conn.GetSysLog(pid)
					if err != nil {
						glog.Warningf("WARNING: failed to fetch syslog: %s", err)
						// Include this warning inline so it is visible in fuzzer logs
						fmt.Fprintf(out, "WARNING: failed to fetch syslog: %s\n", err)
					} else {
						io.WriteString(out, log+"\n")
					}
				}
			}
			io.WriteString(out, line+"\n")
		}

		scanErr <- scanner.Err()
		artifactsCh <- artifacts
	}()

	return scanErr, artifactsCh
}

// Run the fuzzer, sending symbolized output to out and copying any referenced artifacts (e.g.
// crashes) to the artifactDir.
func (f *Fuzzer) Run(conn Connector, out io.Writer, artifactDir string) error {
	if f.options == nil {
		return fmt.Errorf("Run called on Fuzzer before Parse")
	}

	cmdline := []string{f.url}
	for k, v := range f.options {
		cmdline = append(cmdline, fmt.Sprintf("-%s=%s", k, v))
	}
	for _, arg := range f.args {
		cmdline = append(cmdline, arg)
	}
	cmd := conn.Command("run", cmdline...)
	fuzzerOutput, err := cmd.StdoutPipe()
	if err != nil {
		return err
	}
	if err := cmd.Start(); err != nil {
		return err
	}

	fromScanner, toSymbolizer := io.Pipe()

	// Start goroutine to scan for artifact names and PID
	scanErr, artifactsCh := scanFuzzerOutput(conn, toSymbolizer, fuzzerOutput)

	// Start symbolizer goroutine, connected to the output
	symErr := make(chan error, 1)
	go func(in io.Reader) {
		symErr <- f.build.Symbolize(in, out)
	}(fromScanner)

	err = cmd.Wait()
	glog.Infof("Fuzzer run has completed")

	// Check the returncode (though this might be modified
	// by libfuzzer args and thus be unreliable)
	if cmderr, ok := err.(*InstanceCmdError); ok {
		found := false
		for _, code := range expectedFuzzerReturnCodes {
			if cmderr.ReturnCode == code {
				found = true
				break
			}
		}
		if !found {
			return fmt.Errorf("unexpected return code: %s", err)
		}
	} else if err != nil {
		return fmt.Errorf("failed during wait: %s", err)
	}

	// Check for any errors in the goroutines
	if err := <-symErr; err != nil {
		return fmt.Errorf("failed during symbolization: %s", err)
	}
	if err := <-scanErr; err != nil {
		return fmt.Errorf("failed during scanning: %s", err)
	}

	// TODO(fxb/47370): implement this, possibly elsewhere
	for _, artifact := range <-artifactsCh {
		glog.Infof("should fetch artifact %s", f.AbsPath(artifact))
	}

	return nil
}
