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

// +build aetest

package dash

import (
	"strings"
	"testing"
	"time"

	"github.com/google/syzkaller/dashboard/dashapi"
)

func TestEmailNotifUpstreamEmbargo(t *testing.T) {
	c := NewCtx(t)
	defer c.Close()

	build := testBuild(1)
	c.client2.UploadBuild(build)

	crash := testCrash(build, 1)
	c.client2.ReportCrash(crash)
	report := c.pollEmailBug()
	c.expectEQ(report.To, []string{"test@syzkaller.com"})

	// Upstreaming happens after 14 days, so no emails yet.
	c.advanceTime(13 * 24 * time.Hour)
	c.expectNoEmail()

	// Now we should get notification about upstreaming and upstream report:
	c.advanceTime(2 * 24 * time.Hour)
	notifUpstream := c.pollEmailBug()
	upstreamReport := c.pollEmailBug()
	c.expectEQ(notifUpstream.Sender, report.Sender)
	c.expectEQ(notifUpstream.Body, "Sending this report upstream.")
	c.expectNE(upstreamReport.Sender, report.Sender)
	c.expectEQ(upstreamReport.To, []string{"bugs@syzkaller.com", "default@maintainers.com"})
}

func TestEmailNotifUpstreamSkip(t *testing.T) {
	c := NewCtx(t)
	defer c.Close()

	build := testBuild(1)
	c.client2.UploadBuild(build)

	crash := testCrash(build, 1)
	crash.Title = "skip with repro 1"
	c.client2.ReportCrash(crash)
	report := c.pollEmailBug()
	c.expectEQ(report.To, []string{"test@syzkaller.com"})

	// No emails yet.
	c.expectNoEmail()

	// Now upload repro and it should be auto-upstreamed.
	crash.ReproOpts = []byte("repro opts")
	crash.ReproSyz = []byte("getpid()")
	c.client2.ReportCrash(crash)
	notifUpstream := c.pollEmailBug()
	upstreamReport := c.pollEmailBug()
	c.expectEQ(notifUpstream.Sender, report.Sender)
	c.expectEQ(notifUpstream.Body, "Sending this report upstream.")
	c.expectNE(upstreamReport.Sender, report.Sender)
	c.expectEQ(upstreamReport.To, []string{"bugs@syzkaller.com", "default@maintainers.com"})
}

func TestEmailNotifBadFix(t *testing.T) {
	c := NewCtx(t)
	defer c.Close()

	build := testBuild(1)
	c.client2.UploadBuild(build)

	crash := testCrash(build, 1)
	c.client2.ReportCrash(crash)
	report := c.pollEmailBug()
	c.expectEQ(report.To, []string{"test@syzkaller.com"})

	c.incomingEmail(report.Sender, "#syz fix some: commit title")
	c.expectNoEmail()

	// Notification about bad fixing commit should be send after 90 days.
	c.advanceTime(50 * 24 * time.Hour)
	c.expectNoEmail()
	c.advanceTime(35 * 24 * time.Hour)
	c.expectNoEmail()
	c.advanceTime(10 * 24 * time.Hour)
	notif := c.pollEmailBug()
	if !strings.Contains(notif.Body, "This bug is marked as fixed by commit:\nsome: commit title\n") {
		t.Fatalf("bad notification text: %q", notif.Body)
	}
	// No notifications for another 14 days, then another one.
	c.advanceTime(13 * 24 * time.Hour)
	c.expectNoEmail()
	c.advanceTime(2 * 24 * time.Hour)
	notif = c.pollEmailBug()
	if !strings.Contains(notif.Body, "This bug is marked as fixed by commit:\nsome: commit title\n") {
		t.Fatalf("bad notification text: %q", notif.Body)
	}
}

func TestEmailNotifObsoleted(t *testing.T) {
	c := NewCtx(t)
	defer c.Close()

	build := testBuild(1)
	c.client2.UploadBuild(build)

	crash := testCrash(build, 1)
	crash.Maintainers = []string{"maintainer@syzkaller.com"}
	c.client2.ReportCrash(crash)
	report := c.pollEmailBug()
	// Need to upstream so that it's not auto-upstreamed before obsoleted.
	c.incomingEmail(report.Sender, "#syz upstream")
	report = c.pollEmailBug()
	// Add more people to bug CC.
	c.incomingEmail(report.Sender, "wow", EmailOptCC([]string{"somebody@else.com"}))

	// Bug is open, new crashes don't create new bug.
	c.client2.ReportCrash(crash)
	c.expectNoEmail()

	// Not yet.
	c.advanceTime(179 * 24 * time.Hour)
	c.expectNoEmail()

	// Now!
	c.advanceTime(2 * 24 * time.Hour)
	notif := c.pollEmailBug()
	if !strings.Contains(notif.Body, "Auto-closing this bug as obsolete") {
		t.Fatalf("bad notification text: %q", notif.Body)
	}
	c.expectEQ(notif.To, []string{"bugs@syzkaller.com", "default@sender.com", "somebody@else.com"})

	// New crash must create new bug.
	c.client2.ReportCrash(crash)
	report = c.pollEmailBug()
	c.expectEQ(report.Subject, "title1 (2)")
	// Now the same, but for the last reporting (must have smaller CC list).
	c.incomingEmail(report.Sender, "#syz upstream")
	report = c.pollEmailBug()
	c.incomingEmail(report.Sender, "#syz upstream")
	report = c.pollEmailBug()

	c.advanceTime(181 * 24 * time.Hour)
	notif = c.pollEmailBug()
	if !strings.Contains(notif.Body, "Auto-closing this bug as obsolete") {
		t.Fatalf("bad notification text: %q", notif.Body)
	}
	c.expectEQ(notif.To, []string{"bugs2@syzkaller.com"})
}

func TestEmailNotifNotObsoleted(t *testing.T) {
	c := NewCtx(t)
	defer c.Close()

	build := testBuild(1)
	c.client2.UploadBuild(build)

	// Crashes with repro are not auto-obsoleted.
	crash1 := testCrash(build, 1)
	crash1.ReproSyz = []byte("repro")
	c.client2.ReportCrash(crash1)
	report1 := c.pollEmailBug()
	c.incomingEmail(report1.Sender, "#syz upstream")
	report1 = c.pollEmailBug()

	// This crash will get another crash later.
	crash2 := testCrash(build, 2)
	c.client2.ReportCrash(crash2)
	report2 := c.pollEmailBug()
	c.incomingEmail(report2.Sender, "#syz upstream")
	report2 = c.pollEmailBug()

	// This crash will get some activity later.
	crash3 := testCrash(build, 3)
	c.client2.ReportCrash(crash3)
	report3 := c.pollEmailBug()
	c.incomingEmail(report3.Sender, "#syz upstream")
	report3 = c.pollEmailBug()

	// This will be obsoleted (just to check that we have timings right).
	c.advanceTime(24 * time.Hour)
	crash4 := testCrash(build, 4)
	c.client2.ReportCrash(crash4)
	report4 := c.pollEmailBug()
	c.incomingEmail(report4.Sender, "#syz upstream")
	report4 = c.pollEmailBug()

	c.advanceTime(179 * 24 * time.Hour)
	c.expectNoEmail()

	c.client2.ReportCrash(crash2)
	c.incomingEmail(report3.Sender, "I am looking at it")

	c.advanceTime(5 * 24 * time.Hour)
	// Only crash 4 is obsoleted.
	notif := c.pollEmailBug()
	c.expectEQ(notif.Sender, report4.Sender)
	c.expectNoEmail()

	// Crash 3 also obsoleted after some time.
	c.advanceTime(20 * 24 * time.Hour)
	notif = c.pollEmailBug()
	c.expectEQ(notif.Sender, report3.Sender)
}

func TestExtNotifUpstreamEmbargo(t *testing.T) {
	c := NewCtx(t)
	defer c.Close()

	build1 := testBuild(1)
	c.client.UploadBuild(build1)

	crash1 := testCrash(build1, 1)
	c.client.ReportCrash(crash1)
	rep := c.client.pollBug()

	// Specify fixing commit for the bug.
	reply, _ := c.client.ReportingUpdate(&dashapi.BugUpdate{
		ID:     rep.ID,
		Status: dashapi.BugStatusOpen,
	})
	c.expectEQ(reply.OK, true)
	c.client.pollNotifs(0)
	c.advanceTime(20 * 24 * time.Hour)
	notif := c.client.pollNotifs(1)[0]
	c.expectEQ(notif.ID, rep.ID)
	c.expectEQ(notif.Type, dashapi.BugNotifUpstream)
}

func TestExtNotifUpstreamOnHold(t *testing.T) {
	c := NewCtx(t)
	defer c.Close()

	build1 := testBuild(1)
	c.client.UploadBuild(build1)

	crash1 := testCrash(build1, 1)
	c.client.ReportCrash(crash1)
	rep := c.client.pollBug()

	// Specify fixing commit for the bug.
	reply, _ := c.client.ReportingUpdate(&dashapi.BugUpdate{
		ID:     rep.ID,
		Status: dashapi.BugStatusOpen,
		OnHold: true,
	})
	c.expectEQ(reply.OK, true)
	c.advanceTime(20 * 24 * time.Hour)
	c.client.pollNotifs(0)
}
