// Copyright 2021 The Go 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 task

import (
	"bytes"
	"context"
	"net/mail"
	"os"
	"path/filepath"
	"strings"
	"testing"
	"time"

	"github.com/google/go-cmp/cmp"
	"golang.org/x/build/internal/workflow"
)

// Test that the task doesn't start running if the provided
// context doesn't have sufficient time for the task to run.
func TestAnnounceReleaseShortContext(t *testing.T) {
	ctx, cancel := context.WithTimeout(context.Background(), time.Second)
	defer cancel()
	_, err := (AnnounceMailTasks{}).AnnounceRelease(&workflow.TaskContext{Context: ctx}, []string{"go1.18.1", "go1.17.8"}, nil, nil)
	if err == nil {
		t.Errorf("want non-nil error")
	} else if !strings.HasPrefix(err.Error(), "insufficient time") {
		t.Errorf("want error that starts with 'insufficient time' instead of: %s", err)
	}
}

func TestAnnouncementMail(t *testing.T) {
	tests := [...]struct {
		name        string
		in          any
		wantSubject string
	}{
		{
			name: "announce-minor",
			in: releaseAnnouncement{
				Version:          "go1.18.1",
				SecondaryVersion: "go1.17.9",
				Names:            []string{"Alice", "Bob", "Charlie"},
			},
			wantSubject: "Go 1.18.1 and Go 1.17.9 are released",
		},
		{
			name: "announce-minor-with-security",
			in: releaseAnnouncement{
				Version:          "go1.18.1",
				SecondaryVersion: "go1.17.9",
				Security: []string{
					`encoding/pem: fix stack overflow in Decode

A large (more than 5 MB) PEM input can cause a stack overflow in Decode, leading the program to crash.

Thanks to Juho Nurminen of Mattermost who reported the error.

This is CVE-2022-24675 and https://go.dev/issue/51853.`,
					`crypto/elliptic: tolerate all oversized scalars in generic P-256

A crafted scalar input longer than 32 bytes can cause P256().ScalarMult or P256().ScalarBaseMult to panic. Indirect uses through crypto/ecdsa and crypto/tls are unaffected. amd64, arm64, ppc64le, and s390x are unaffected.

This was discovered thanks to a Project Wycheproof test vector.

This is CVE-2022-28327 and https://go.dev/issue/52075.`,
					`crypto/x509: non-compliant certificates can cause a panic in Verify on macOS in Go 1.18

Verifying certificate chains containing certificates which are not compliant with RFC 5280 causes Certificate.Verify to panic on macOS.

These chains can be delivered through TLS and can cause a crypto/tls or net/http client to crash.

Thanks to Tailscale for doing weird things and finding this.

This is CVE-2022-27536 and https://go.dev/issue/51759.`,
				},
			},
			wantSubject: "[security] Go 1.18.1 and Go 1.17.9 are released",
		},
		{
			name: "announce-minor-solo",
			in: releaseAnnouncement{
				Version:  "go1.11.1",
				Security: []string{"abc: security fix 1", "xyz: security fix 2"},
				Names:    []string{"Alice"},
			},
			wantSubject: "[security] Go 1.11.1 is released",
		},
		{
			name: "announce-beta",
			in: releaseAnnouncement{
				Version: "go1.19beta5",
			},
			wantSubject: "Go 1.19 Beta 5 is released",
		},
		{
			name: "announce-rc",
			in: releaseAnnouncement{
				Version: "go1.19rc6",
			},
			wantSubject: "Go 1.19 Release Candidate 6 is released",
		},
		{
			name: "announce-major",
			in: releaseAnnouncement{
				Version: "go1.19",
			},
			wantSubject: "Go 1.19 is released",
		},

		{
			name: "pre-announce-minor",
			in: releasePreAnnouncement{
				Target:           Date{2022, time.July, 12},
				Version:          "go1.18.4",
				SecondaryVersion: "go1.17.12",
				Security:         "the standard library",
				CVEs:             []string{"cve-1234", "cve-5678"},
				Names:            []string{"Alice"},
			},
			wantSubject: "[security] Go 1.18.4 and Go 1.17.12 pre-announcement",
		},
		{
			name: "pre-announce-minor-solo",
			in: releasePreAnnouncement{
				Target:   Date{2022, time.July, 12},
				Version:  "go1.18.4",
				Security: "the toolchain",
				CVEs:     []string{"cve-1234", "cve-5678"},
				Names:    []string{"Alice", "Bob"},
			},
			wantSubject: "[security] Go 1.18.4 pre-announcement",
		},
	}
	for _, tc := range tests {
		t.Run(tc.name, func(t *testing.T) {
			m, err := announcementMail(tc.in)
			if err != nil {
				t.Fatal("announcementMail returned non-nil error:", err)
			}
			if *updateFlag {
				writeTestdataFile(t, tc.name+".html", []byte(m.BodyHTML))
				writeTestdataFile(t, tc.name+".txt", []byte(m.BodyText))
				return
			}
			if diff := cmp.Diff(tc.wantSubject, m.Subject); diff != "" {
				t.Errorf("subject mismatch (-want +got):\n%s", diff)
			}
			if diff := cmp.Diff(testdataFile(t, tc.name+".html"), m.BodyHTML); diff != "" {
				t.Errorf("body HTML mismatch (-want +got):\n%s", diff)
			}
			if diff := cmp.Diff(testdataFile(t, tc.name+".txt"), m.BodyText); diff != "" {
				t.Errorf("body text mismatch (-want +got):\n%s", diff)
			}
			if t.Failed() {
				t.Log("\n\n(if the new output is intentional, use -update flag to update goldens)")
			}
		})
	}
}

// testdataFile reads the named file in the testdata directory.
func testdataFile(t *testing.T, name string) string {
	t.Helper()
	b, err := os.ReadFile(filepath.Join("testdata", name))
	if err != nil {
		t.Fatal(err)
	}
	return string(b)
}

// writeTestdataFile writes the named file in the testdata directory.
func writeTestdataFile(t *testing.T, name string, data []byte) {
	t.Helper()
	err := os.WriteFile(filepath.Join("testdata", name), data, 0644)
	if err != nil {
		t.Fatal(err)
	}
}

func TestAnnounceRelease(t *testing.T) {
	if testing.Short() {
		t.Skip("not running test that uses internet in short mode")
	}

	tests := [...]struct {
		name         string
		versions     []string
		security     []string
		coordinators []string
		want         SentMail
		wantLog      string
	}{
		{
			name:         "minor",
			versions:     []string{"go1.18.1", "go1.17.8"}, // Intentionally not 1.17.9 so the real email doesn't get in the way.
			coordinators: []string{"heschi", "dmitshur"},
			want:         SentMail{Subject: "Go 1.18.1 and Go 1.17.8 are released"},
			wantLog: `announcement subject: Go 1.18.1 and Go 1.17.8 are released

announcement body HTML:
<p>Hello gophers,</p>
<p>We have just released Go versions 1.18.1 and 1.17.8, minor point releases.</p>
<p>View the release notes for more information:<br>
<a href="https://go.dev/doc/devel/release#go1.18.1">https://go.dev/doc/devel/release#go1.18.1</a></p>
<p>You can download binary and source distributions from the Go website:<br>
<a href="https://go.dev/dl/">https://go.dev/dl/</a></p>
<p>To compile from source using a Git clone, update to the release with<br>
<code>git checkout go1.18.1</code> and build as usual.</p>
<p>Thanks to everyone who contributed to the releases.</p>
<p>Cheers,<br>
Heschi and Dmitri for the Go team</p>

announcement body text:
Hello gophers,

We have just released Go versions 1.18.1 and 1.17.8, minor point releases.

View the release notes for more information:
https://go.dev/doc/devel/release#go1.18.1

You can download binary and source distributions from the Go website:
https://go.dev/dl/

To compile from source using a Git clone, update to the release with
git checkout go1.18.1 and build as usual.

Thanks to everyone who contributed to the releases.

Cheers,
Heschi and Dmitri for the Go team` + "\n",
		},
		// Just one test case is enough, since TestAnnouncementMail
		// has very thorough coverage for all release types.
	}
	for _, tc := range tests {
		t.Run(tc.name, func(t *testing.T) {
			annMail := MailHeader{
				From: mail.Address{Address: "from-address@golang.test"},
				To:   mail.Address{Address: "to-address@golang.test"},
			}
			tasks := AnnounceMailTasks{
				SendMail: func(h MailHeader, c MailContent) error {
					if diff := cmp.Diff(annMail, h); diff != "" {
						t.Errorf("mail header mismatch (-want +got):\n%s", diff)
					}
					if diff := cmp.Diff(tc.want.Subject, c.Subject); diff != "" {
						t.Errorf("mail subject mismatch (-want +got):\n%s", diff)
					}
					return nil
				},
				AnnounceMailHeader: annMail,
			}
			var buf bytes.Buffer
			ctx := &workflow.TaskContext{Context: context.Background(), Logger: fmtWriter{&buf}}
			sentMail, err := tasks.AnnounceRelease(ctx, tc.versions, tc.security, tc.coordinators)
			if err != nil {
				t.Fatal("task function returned non-nil error:", err)
			}
			if diff := cmp.Diff(tc.want, sentMail); diff != "" {
				t.Errorf("sent mail mismatch (-want +got):\n%s", diff)
			}
			if diff := cmp.Diff(tc.wantLog, buf.String()); diff != "" {
				t.Errorf("log mismatch (-want +got):\n%s", diff)
			}
		})
	}
}

func TestPreAnnounceRelease(t *testing.T) {
	if testing.Short() {
		t.Skip("not running test that uses internet in short mode")
	}

	tests := [...]struct {
		name         string
		versions     []string
		target       Date
		security     string
		cves         []string
		coordinators []string
		want         SentMail
		wantLog      string
	}{
		{
			name:         "minor",
			versions:     []string{"go1.18.4", "go1.17.11"}, // Intentionally not 1.17.12 so the real email doesn't get in the way.
			target:       Date{2022, time.July, 12},
			security:     "the standard library",
			cves:         []string{"cve-2022-1234", "cve-2023-1234"},
			coordinators: []string{"tatiana"},
			want:         SentMail{Subject: "[security] Go 1.18.4 and Go 1.17.11 pre-announcement"},
			wantLog: `pre-announcement subject: [security] Go 1.18.4 and Go 1.17.11 pre-announcement

pre-announcement body HTML:
<p>Hello gophers,</p>
<p>We plan to issue Go 1.18.4 and Go 1.17.11 during US business hours on Tuesday, July 12.</p>
<p>These minor releases include PRIVATE security fixes to the standard library, covering the following CVEs:</p>
<ul>
<li>cve-2022-1234</li>
<li>cve-2023-1234</li>
</ul>
<p>Following our security policy, this is the pre-announcement of those releases.</p>
<p>Thanks,<br>
Tatiana for the Go team</p>

pre-announcement body text:
Hello gophers,

We plan to issue Go 1.18.4 and Go 1.17.11 during US business hours on Tuesday, July 12.

These minor releases include PRIVATE security fixes to the standard library, covering the following CVEs:

-	cve-2022-1234

-	cve-2023-1234

Following our security policy, this is the pre-announcement of those releases.

Thanks,
Tatiana for the Go team` + "\n",
		},
		// TestAnnouncementMail has additional coverage.
	}
	for _, tc := range tests {
		t.Run(tc.name, func(t *testing.T) {
			tasks := AnnounceMailTasks{
				SendMail:    func(h MailHeader, c MailContent) error { return nil },
				testHookNow: func() time.Time { return time.Date(2022, time.July, 7, 0, 0, 0, 0, time.UTC) },
			}
			var buf bytes.Buffer
			ctx := &workflow.TaskContext{Context: context.Background(), Logger: fmtWriter{&buf}}
			sentMail, err := tasks.PreAnnounceRelease(ctx, tc.versions, tc.target, tc.security, tc.cves, tc.coordinators)
			if err != nil {
				t.Fatal("task function returned non-nil error:", err)
			}
			if diff := cmp.Diff(tc.want, sentMail); diff != "" {
				t.Errorf("sent mail mismatch (-want +got):\n%s", diff)
			}
			if diff := cmp.Diff(tc.wantLog, buf.String()); diff != "" {
				t.Errorf("log mismatch (-want +got):\n%s", diff)
			}
		})
	}
}

func TestFindGoogleGroupsThread(t *testing.T) {
	if testing.Short() {
		t.Skip("not running test that uses internet in short mode")
	}

	threadURL, err := findGoogleGroupsThread(&workflow.TaskContext{
		Context: context.Background(),
	}, "[security] Go 1.18.3 and Go 1.17.11 are released")
	if err != nil {
		// Note: These test failures are only actionable if the error is not
		// a transient network one.
		t.Fatalf("findGoogleGroupsThread returned a non-nil error: %v", err)
	}
	// Just log the threadURL since we can't rely on stable output.
	// This test is mostly for debugging if we need to.
	t.Logf("threadURL: %q\n", threadURL)
}

func TestMarkdownToText(t *testing.T) {
	const in = `Hello gophers,

This is a simple Markdown document that exercises
a limited set of features used in email templates.

There may be security fixes following the [security policy](https://go.dev/security):

-	abc: Read hangs on extremely large input

	On an operating system, ` + "`Read`" + ` will hang indefinitely if
	the buffer size is larger than 1 << 64 - 1 bytes.

	Thanks to Gopher A for reporting the issue.

	This is CVE-123 and Go issue https://go.dev/issue/123.

-	xyz: Clean("X") returns "Y" when Z

	Some description of the problem here.

	Markdown allows one to use backslash escapes, like \_underscore\_
	or \*literal asterisks\*, so we might encounter that.

View release notes:
https://go.dev/doc/devel/release#go1.18.3

You can download binaries:
https://go.dev/dl/

To builds from source, use
` + "`git checkout`" + `.

An easy way to try go1.19beta1
is by using the go command:
$ go install example.org@latest
$ example download

That's all for now.
`
	_, got, err := renderMarkdown(strings.NewReader(in))
	if err != nil {
		t.Fatal(err)
	}

	const want = `Hello gophers,

This is a simple Markdown document that exercises
a limited set of features used in email templates.

There may be security fixes following the security policy <https://go.dev/security>:

-	abc: Read hangs on extremely large input

	On an operating system, Read will hang indefinitely if
	the buffer size is larger than 1 << 64 - 1 bytes.

	Thanks to Gopher A for reporting the issue.

	This is CVE-123 and Go issue https://go.dev/issue/123.

-	xyz: Clean("X") returns "Y" when Z

	Some description of the problem here.

	Markdown allows one to use backslash escapes, like \_underscore\_
	or \*literal asterisks\*, so we might encounter that.

View release notes:
https://go.dev/doc/devel/release#go1.18.3

You can download binaries:
https://go.dev/dl/

To builds from source, use
git checkout.

An easy way to try go1.19beta1
is by using the go command:
$ go install example.org@latest
$ example download

That's all for now.
`
	if diff := cmp.Diff(want, got); diff != "" {
		t.Errorf("plain text rendering mismatch (-want +got):\n%s", diff)
	}
}
