// Copyright 2018 syzkaller project authors. All rights reserved.
// Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file.

// Runtest runs syzkaller test programs in sys/*/test/*. Start as:
// $ syz-runtest -config manager.config
// Also see pkg/runtest docs.
package main

import (
	"errors"
	"flag"
	"fmt"
	"io/ioutil"
	"log"
	"net"
	"os"
	"path/filepath"
	"sync"
	"time"

	"github.com/google/syzkaller/pkg/instance"
	"github.com/google/syzkaller/pkg/mgrconfig"
	"github.com/google/syzkaller/pkg/osutil"
	"github.com/google/syzkaller/pkg/report"
	"github.com/google/syzkaller/pkg/rpctype"
	"github.com/google/syzkaller/pkg/runtest"
	"github.com/google/syzkaller/prog"
	"github.com/google/syzkaller/sys"
	"github.com/google/syzkaller/vm"
)

var (
	flagConfig = flag.String("config", "", "manager config")
	flagDebug  = flag.Bool("debug", false, "debug mode")
)

func main() {
	flag.Parse()
	cfg, err := mgrconfig.LoadFile(*flagConfig)
	if err != nil {
		log.Fatal(err)
	}
	target, err := prog.GetTarget(cfg.TargetOS, cfg.TargetArch)
	if err != nil {
		log.Fatal(err)
	}
	vmPool, err := vm.Create(cfg, *flagDebug)
	if err != nil {
		log.Fatal(err)
	}
	reporter, err := report.NewReporter(cfg)
	if err != nil {
		log.Fatal(err)
	}
	osutil.MkdirAll(cfg.Workdir)
	mgr := &Manager{
		cfg:              cfg,
		target:           target,
		vmPool:           vmPool,
		reporter:         reporter,
		debug:            *flagDebug,
		requests:         make(chan *runtest.RunRequest, 2*vmPool.Count()),
		checkResultC:     make(chan *rpctype.CheckArgs, 1),
		checkResultReady: make(chan bool),
		vmStop:           make(chan bool),
		reqMap:           make(map[int]*runtest.RunRequest),
		lastReq:          make(map[string]int),
	}
	s, err := rpctype.NewRPCServer(cfg.RPC, mgr)
	if err != nil {
		log.Fatalf("failed to create rpc server: %v", err)
	}
	mgr.port = s.Addr().(*net.TCPAddr).Port
	go s.Serve()
	var wg sync.WaitGroup
	wg.Add(vmPool.Count())
	fmt.Printf("booting VMs...\n")
	for i := 0; i < vmPool.Count(); i++ {
		i := i
		go func() {
			defer wg.Done()
			name := fmt.Sprintf("vm-%v", i)
			for {
				rep, err := mgr.boot(name, i)
				if err != nil {
					log.Fatal(err)
				}
				if rep == nil {
					return
				}
				if err := mgr.finishRequest(name, rep); err != nil {
					log.Fatal(err)
				}
			}
		}()
	}
	mgr.checkResult = <-mgr.checkResultC
	close(mgr.checkResultReady)
	enabledCalls := make(map[string]map[*prog.Syscall]bool)
	for sandbox, ids := range mgr.checkResult.EnabledCalls {
		calls := make(map[*prog.Syscall]bool)
		for _, id := range ids {
			calls[target.Syscalls[id]] = true
		}
		enabledCalls[sandbox] = calls
	}
	for _, feat := range mgr.checkResult.Features {
		fmt.Printf("%-24v: %v\n", feat.Name, feat.Reason)
	}
	for sandbox, calls := range enabledCalls {
		fmt.Printf("%-24v: %v calls enabled\n", sandbox+" sandbox", len(calls))
	}
	ctx := &runtest.Context{
		Dir:          filepath.Join(cfg.Syzkaller, "sys", target.OS, "test"),
		Target:       target,
		Features:     mgr.checkResult.Features,
		EnabledCalls: enabledCalls,
		Requests:     mgr.requests,
		LogFunc:      func(text string) { fmt.Println(text) },
	}
	err = ctx.Run()
	close(vm.Shutdown)
	wg.Wait()
	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}
}

type Manager struct {
	cfg              *mgrconfig.Config
	target           *prog.Target
	vmPool           *vm.Pool
	reporter         report.Reporter
	requests         chan *runtest.RunRequest
	checkResult      *rpctype.CheckArgs
	checkResultReady chan bool
	checkResultC     chan *rpctype.CheckArgs
	vmStop           chan bool
	port             int
	debug            bool

	reqMu   sync.Mutex
	reqSeq  int
	reqMap  map[int]*runtest.RunRequest
	lastReq map[string]int
}

func (mgr *Manager) boot(name string, index int) (*report.Report, error) {
	inst, err := mgr.vmPool.Create(index)
	if err != nil {
		return nil, fmt.Errorf("failed to create instance: %v", err)
	}
	defer inst.Close()

	fwdAddr, err := inst.Forward(mgr.port)
	if err != nil {
		return nil, fmt.Errorf("failed to setup port forwarding: %v", err)
	}
	fuzzerBin, err := inst.Copy(mgr.cfg.SyzFuzzerBin)
	if err != nil {
		return nil, fmt.Errorf("failed to copy binary: %v", err)
	}
	executorBin, err := inst.Copy(mgr.cfg.SyzExecutorBin)
	if err != nil {
		return nil, fmt.Errorf("failed to copy binary: %v", err)
	}
	cmd := instance.FuzzerCmd(fuzzerBin, executorBin, name,
		mgr.cfg.TargetOS, mgr.cfg.TargetArch, fwdAddr, mgr.cfg.Sandbox, mgr.cfg.Procs, 0,
		mgr.cfg.Cover, mgr.debug, false, true)
	outc, errc, err := inst.Run(time.Hour, mgr.vmStop, cmd)
	if err != nil {
		return nil, fmt.Errorf("failed to run fuzzer: %v", err)
	}
	rep := inst.MonitorExecution(outc, errc, mgr.reporter, true)
	return rep, nil
}

func (mgr *Manager) finishRequest(name string, rep *report.Report) error {
	mgr.reqMu.Lock()
	defer mgr.reqMu.Unlock()
	lastReq := mgr.lastReq[name]
	req := mgr.reqMap[lastReq]
	if lastReq == 0 || req == nil {
		return fmt.Errorf("vm crash: %v\n%s\n%s", rep.Title, rep.Report, rep.Output)
	}
	delete(mgr.reqMap, lastReq)
	delete(mgr.lastReq, name)
	req.Err = fmt.Errorf("%v", rep.Title)
	req.Output = rep.Report
	if len(req.Output) == 0 {
		req.Output = rep.Output
	}
	close(req.Done)
	return nil
}

func (mgr *Manager) Connect(a *rpctype.ConnectArgs, r *rpctype.ConnectRes) error {
	r.GitRevision = sys.GitRevision
	r.TargetRevision = mgr.target.Revision
	r.AllSandboxes = true
	select {
	case <-mgr.checkResultReady:
		r.CheckResult = mgr.checkResult
	default:
	}
	return nil
}

func (mgr *Manager) Check(a *rpctype.CheckArgs, r *int) error {
	if a.Error != "" {
		log.Fatalf("machine check: %v", a.Error)
	}
	select {
	case mgr.checkResultC <- a:
	default:
	}
	return nil
}

func (mgr *Manager) Poll(a *rpctype.RunTestPollReq, r *rpctype.RunTestPollRes) error {
	req := <-mgr.requests
	if req == nil {
		return nil
	}
	mgr.reqMu.Lock()
	if mgr.lastReq[a.Name] != 0 {
		log.Fatalf("double poll req from %v", a.Name)
	}
	mgr.reqSeq++
	r.ID = mgr.reqSeq
	mgr.reqMap[mgr.reqSeq] = req
	mgr.lastReq[a.Name] = mgr.reqSeq
	mgr.reqMu.Unlock()
	if req.Bin != "" {
		data, err := ioutil.ReadFile(req.Bin)
		if err != nil {
			log.Fatalf("failed to read bin file: %v", err)
		}
		r.Bin = data
		return nil
	}
	r.Prog = req.P.Serialize()
	r.Cfg = req.Cfg
	r.Opts = req.Opts
	r.Repeat = req.Repeat
	return nil
}

func (mgr *Manager) Done(a *rpctype.RunTestDoneArgs, r *int) error {
	mgr.reqMu.Lock()
	lastReq := mgr.lastReq[a.Name]
	if lastReq != a.ID {
		log.Fatalf("wrong done id %v from %v", a.ID, a.Name)
	}
	req := mgr.reqMap[a.ID]
	delete(mgr.reqMap, a.ID)
	delete(mgr.lastReq, a.Name)
	mgr.reqMu.Unlock()
	if req == nil {
		log.Fatalf("got done request for unknown id %v", a.ID)
	}
	req.Output = a.Output
	req.Info = a.Info
	if a.Error != "" {
		req.Err = errors.New(a.Error)
	}
	close(req.Done)
	return nil
}
