// Copyright 2023 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 report

import (
	"testing"

	"github.com/google/go-cmp/cmp"
	"golang.org/x/vulndb/internal/proxy"
)

func TestFix(t *testing.T) {
	r := Report{
		Modules: []*Module{
			{
				Module: "std",
				Versions: []VersionRange{
					{
						Introduced: "go1.20",
					},
					{
						Fixed: "go1.20.1",
					},
					{
						Introduced: "go1.19",
						Fixed:      "go1.19.5",
					},
					{
						Fixed: "go1.18.5",
					},
				},
				VulnerableAt: "go1.20",
			},
			{
				Module: "golang.org/x/vulndb",
				Versions: []VersionRange{{
					Introduced: "0cbf4ffdb4e70fce663ec8d59198745b04e7801b",
				}},
				VulnerableAt: "0cbf4ffdb4e70fce663ec8d59198745b04e7801b",
			},
		},
		Description: "A long form description of the problem that will be broken up into multiple lines so it is more readable.",
		References: []*Reference{
			{
				URL: "https://github.com/golang/go/issues/123",
			},
		},
	}
	want := Report{
		Summary: "Vulnerability in golang.org/x/vulndb",
		Modules: []*Module{
			{
				Module: "std",
				Versions: []VersionRange{
					{
						Fixed: "1.18.5",
					},
					{
						Introduced: "1.19.0",
						Fixed:      "1.19.5",
					},
					{
						Introduced: "1.20.0",
						Fixed:      "1.20.1",
					},
				},
				VulnerableAt: "1.20.0",
			},
			{
				Module: "golang.org/x/vulndb",
				Versions: []VersionRange{{
					Introduced: "0.0.0-20230522180520-0cbf4ffdb4e7",
				}},
				VulnerableAt: "0.0.0-20230522180520-0cbf4ffdb4e7",
			},
		},
		Description: "A long form description of the problem that will be broken up into multiple\nlines so it is more readable.",
		References: []*Reference{
			{
				URL: "https://go.dev/issue/123",
			},
		},
	}

	pc, err := proxy.NewTestClient(t, *realProxy)
	if err != nil {
		t.Fatal(err)
	}

	r.Fix(pc)

	got := r
	if diff := cmp.Diff(want, got); diff != "" {
		t.Errorf("Fix() mismatch (-want +got):\n%s", diff)
	}
}

func TestFixLineLength(t *testing.T) {
	tcs := []struct {
		name    string
		n       int
		unfixed string
		want    string
	}{
		{
			name:    "empty",
			n:       1,
			unfixed: "",
			want:    "",
		},
		{
			name: "multiple paragraphs with long lines",
			n:    80,
			unfixed: `Incorrect access control is possible in the go command.

The go command can misinterpret branch names that falsely appear to be version tags.
This can lead to incorrect access control if an actor is authorized to create branches
but not tags.`,
			want: `Incorrect access control is possible in the go command.

The go command can misinterpret branch names that falsely appear to be version
tags. This can lead to incorrect access control if an actor is authorized to
create branches but not tags.`,
		},
		{
			name:    "one paragraph",
			n:       15,
			unfixed: "A single paragraph description.",
			want:    "A single\nparagraph\ndescription.",
		},
		{
			name:    "word longer than max",
			n:       10,
			unfixed: "A single verylongword on its own line is OK",
			want:    "A single\nverylongword\non its own\nline is OK",
		},
		{
			name:    "word longer than max with paragraph",
			n:       10,
			unfixed: "A single\n\nverylongword\n\non its own",
			want:    "A single\n\nverylongword\n\non its own",
		},
		{
			name:    "ok - exactly at max",
			n:       19,
			unfixed: "This is already OK.\nThis is already OK.",
			want:    "This is already OK.\nThis is already OK.",
		},
		{
			name:    "ok - shorter than max",
			n:       20,
			unfixed: "This is already OK.",
			want:    "This is already OK.",
		},
		{
			name: "markdown",
			n:    20,
			unfixed: `Hello

1. this is a point
2. this is a longer point that will be broken up
3. this is point 3`,
			want: `Hello

1. this is a point
2. this is a longer
point that will be
broken up
3. this is point 3`,
		},
	}
	for _, tc := range tcs {
		t.Run(tc.name, func(t *testing.T) {
			got := fixLineLength(tc.unfixed, tc.n)
			if diff := cmp.Diff(tc.want, got); diff != "" {
				t.Errorf("fixLineLength() mismatch (-want +got):\n%s\n%s", diff, got)
			}
		})
	}
}

func TestGuessVulnerableAt(t *testing.T) {
	pc, err := proxy.NewTestClient(t, *realProxy)
	if err != nil {
		t.Fatal(err)
	}
	for _, tc := range []struct {
		name string
		m    *Module
		want string
	}{
		{
			name: "no fix",
			m: &Module{
				Module: "golang.org/x/tools",
			},
			want: "0.12.0", // latest
		},
		{
			name: "has fix",
			m: &Module{
				Module: "golang.org/x/tools",
				Versions: []VersionRange{
					{
						Fixed: "0.1.8",
					},
				},
			},
			want: "0.1.7",
		},
	} {
		t.Run(tc.name, func(t *testing.T) {
			got, err := tc.m.guessVulnerableAt(pc)
			if err != nil {
				t.Fatal(err)
			}
			if got != tc.want {
				t.Errorf("guessVulnerableAt() = %q, want %s", got, tc.want)
			}
		})
	}
}
