// 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 (
	"fmt"
	"io"
	"regexp"
	"strings"
	"time"
)

// mockInstanceCmd is the type returned by mockConnector.Command()
type mockInstanceCmd struct {
	connector *mockConnector
	name      string
	args      []string
	running   bool
	pipeOut   *io.PipeWriter
	errCh     chan error
	timeout   time.Duration
}

func (c *mockInstanceCmd) getOutput() ([]byte, error) {
	switch c.name {
	case "run":
		re := regexp.MustCompile(`fuchsia-pkg://fuchsia\.com/([^#]+)#meta/([^\.]+)\.cmx`)
		m := re.FindStringSubmatch(c.args[0])
		if m == nil {
			return nil, fmt.Errorf("unexpected run argument: %q", c.args[0])
		}
		fuzzerName := fmt.Sprintf("%s/%s", m[1], m[2])

		var output []string
		switch fuzzerName {
		case "foo/bar":
			output = []string{
				fmt.Sprintf("running %v", c.args),
				"==123==", // pid
				"MS: ",    // mut
				"Deadly signal",
				"Test unit written to /some/path", // artifact
			}
		case "fail/nopid":
			// No PID
			output = []string{
				fmt.Sprintf("running %v", c.args),
				"MS: ", // mut
				"Deadly signal",
				"Test unit written to /some/path", // artifact
			}
		case "fail/notfound":
			return nil, &InstanceCmdError{ReturnCode: 127, Command: c.name, Stderr: "not found"}
		default:
			output = []string{fmt.Sprintf("unknown fuzzer %q", fuzzerName)}
		}
		return []byte(strings.Join(output, "\n") + "\n"), nil
	default:
		return nil, fmt.Errorf("unknown command: %q", c.name)
	}
}

func (c *mockInstanceCmd) Output() ([]byte, error) {
	if c.pipeOut != nil {
		return nil, fmt.Errorf("Output called after StdoutPipe")
	}
	c.Run()
	return c.getOutput()
}

func (c *mockInstanceCmd) Run() error {
	err := c.Start()
	if err != nil {
		return err
	}
	return c.Wait()
}

func (c *mockInstanceCmd) Start() error {
	if !c.connector.connected {
		if err := c.connector.Connect(); err != nil {
			return err
		}
	}

	if c.running {
		return fmt.Errorf("Start called when already running")
	}
	c.running = true

	if c.pipeOut != nil {
		// Kick off a goroutine to output everything and then exit. This is a
		// goroutine because the write blocks on the consumer on the other end
		// of the pipe
		c.errCh = make(chan error, 1)
		go func() {
			defer close(c.errCh)
			output, err := c.getOutput()
			if err != nil {
				c.errCh <- err
				return
			}
			_, err = c.pipeOut.Write(output)
			if err != nil {
				c.errCh <- err
				return
			}
			err = c.pipeOut.Close()
			if err != nil {
				c.errCh <- err
				return
			}
		}()
	}
	return nil
}

func (c *mockInstanceCmd) StdinPipe() (io.WriteCloser, error) {
	return nil, fmt.Errorf("not implemented")
}

func (c *mockInstanceCmd) StdoutPipe() (io.ReadCloser, error) {
	r, w := io.Pipe()
	c.pipeOut = w
	return r, nil
}

func (c *mockInstanceCmd) Wait() error {
	// On quit, close stdout in case someone is blocking on us
	if c.pipeOut != nil {
		defer c.pipeOut.Close()
	}

	if !c.running {
		return fmt.Errorf("Wait called when not running")
	}
	c.running = false
	// TODO(fxb/45425): also check 'hasRun'

	if c.errCh != nil {
		if err := <-c.errCh; err != nil {
			return fmt.Errorf("error in goroutine: %s", err)
		}
	}

	return nil
}

func (c *mockInstanceCmd) SetTimeout(duration time.Duration) {
	c.timeout = duration
}

func (c *mockInstanceCmd) Kill() error {
	if !c.running {
		return fmt.Errorf("Kill called when not running")
	}
	c.running = false
	return nil
}
