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

package report

import (
	"bytes"
	"regexp"

	"github.com/google/syzkaller/sys/targets"
)

type gvisor struct {
	ignores []*regexp.Regexp
}

func ctorGvisor(target *targets.Target, kernelSrc, kernelObj string,
	ignores []*regexp.Regexp) (Reporter, []string, error) {
	ctx := &gvisor{
		ignores: ignores,
	}
	suppressions := []string{
		"fatal error: runtime: out of memory",
		"fatal error: runtime: cannot allocate memory",
		"fatal error: newosproc",
		"panic: ptrace sysemu failed: no such process",           // OOM kill
		`panic: ptrace (s|g)et fpregs.* failed: no such process`, // OOM kill
		`panic: ptrace (s|g)et regs.* failed: no such process`,   // OOM kill
		"panic: error initializing first thread: resource temporarily unavailable",
		"panic: failed to start executor binary",
		"panic: executor failed: pthread_create failed",
		"panic: error mapping run data: error mapping runData: cannot allocate memory",
		"ERROR: ThreadSanitizer", // Go race failing due to OOM.
		"FATAL: ThreadSanitizer",
	}
	return ctx, suppressions, nil
}

func (ctx *gvisor) ContainsCrash(output []byte) bool {
	return containsCrash(output, gvisorOopses, ctx.ignores)
}

func (ctx *gvisor) Parse(output []byte) *Report {
	rep := simpleLineParser(output, gvisorOopses, nil, ctx.ignores)
	if rep == nil {
		return nil
	}
	rep.Title = replaceTable(gvisorTitleReplacement, rep.Title)
	rep.Report = ctx.shortenReport(rep.Report)
	return rep
}

func (ctx *gvisor) shortenReport(report []byte) []byte {
	// gvisor panics include stacks of all goroutines.
	// This output is too lengthy for report and not very useful.
	// So we always take 5 lines from report and then cut it at the next empty line.
	// The intention is to capture panic header and traceback of the first goroutine.
	pos := 0
	for i := 0; i < 5; i++ {
		pos1 := bytes.IndexByte(report[pos:], '\n')
		if pos1 == -1 {
			return report
		}
		pos += pos1 + 1
	}
	end := bytes.Index(report[pos:], []byte{'\n', '\n'})
	if end == -1 {
		return report
	}
	if bytes.Contains(report, []byte("WARNING: DATA RACE")) {
		// For data races extract both stacks.
		end2 := bytes.Index(report[pos+end+2:], []byte{'\n', '\n'})
		if end2 != -1 {
			end += end2 + 2
		}
	}
	return report[:pos+end+1]
}

func (ctx *gvisor) Symbolize(rep *Report) error {
	return nil
}

var gvisorTitleReplacement = []replacement{
	{
		regexp.MustCompile(`container ".*"`),
		"container NAME",
	},
	{
		regexp.MustCompile(`sandbox ".*"`),
		"sandbox NAME",
	},
	{
		regexp.MustCompile(`(pid|PID) [0-9]+`),
		"pid X",
	},
}

var gvisorOopses = []*oops{
	{
		[]byte("panic:"),
		[]oopsFormat{
			{
				title:        compile("panic:(.*)"),
				fmt:          "panic:%[1]v",
				noStackTrace: true,
			},
		},
		[]*regexp.Regexp{},
	},
	{
		[]byte("Panic:"),
		[]oopsFormat{
			{
				title:        compile("Panic:(.*)"),
				fmt:          "Panic:%[1]v",
				noStackTrace: true,
			},
		},
		[]*regexp.Regexp{},
	},
	{
		[]byte("fatal error:"),
		[]oopsFormat{
			{
				title:        compile("fatal error:(.*)"),
				fmt:          "fatal error:%[1]v",
				noStackTrace: true,
			},
		},
		[]*regexp.Regexp{},
	},
	{
		[]byte("runtime error:"),
		[]oopsFormat{
			{
				title:        compile("runtime error:(.*)"),
				fmt:          "runtime error:%[1]v",
				noStackTrace: true,
			},
		},
		[]*regexp.Regexp{},
	},
	{
		[]byte("SIGSEGV:"),
		[]oopsFormat{
			{
				title:        compile("SIGSEGV:(.*)"),
				fmt:          "SIGSEGV:%[1]v",
				noStackTrace: true,
			},
		},
		[]*regexp.Regexp{},
	},
	{
		[]byte("SIGBUS:"),
		[]oopsFormat{
			{
				title:        compile("SIGBUS:(.*)"),
				fmt:          "SIGBUS:%[1]v",
				noStackTrace: true,
			},
		},
		[]*regexp.Regexp{},
	},
	{
		[]byte("FATAL ERROR:"),
		[]oopsFormat{
			{
				title:        compile("FATAL ERROR:(.*)"),
				fmt:          "FATAL ERROR:%[1]v",
				noStackTrace: true,
			},
		},
		[]*regexp.Regexp{},
	},
	{
		[]byte("WARNING: DATA RACE"),
		[]oopsFormat{
			{
				title:        compile("WARNING: DATA RACE"),
				report:       compile("WARNING: DATA RACE\n(?:.*\n)*?  (?:[a-zA-Z0-9./-_]+/)([a-zA-Z0-9.()*_]+)\\(\\)\n"),
				fmt:          "DATA RACE in %[1]v",
				noStackTrace: true,
			},
		},
		[]*regexp.Regexp{},
	},
	{
		[]byte("Invalid request partialResult"),
		[]oopsFormat{
			{
				title:        compile("Invalid request partialResult"),
				report:       compile("Invalid request partialResult .* for (.*) operation"),
				fmt:          "Invalid request partialResult in %[1]v",
				noStackTrace: true,
			},
		},
		[]*regexp.Regexp{},
	},
}
