package model

import (
	"testing"

	"github.com/stretchr/testify/assert"

	"github.com/anchore/grype/grype/db/internal/sqlite"
	v5 "github.com/anchore/grype/grype/db/v5"
	"github.com/anchore/grype/grype/db/v5/pkg/qualifier"
	"github.com/anchore/grype/grype/db/v5/pkg/qualifier/platformcpe"
	"github.com/anchore/grype/grype/db/v5/pkg/qualifier/rpmmodularity"
)

func TestVulnerabilityModel_Inflate(t *testing.T) {
	tests := []struct {
		name   string
		record *VulnerabilityModel
		result v5.Vulnerability
	}{
		{
			name: "nil package_qualifiers",
			record: &VulnerabilityModel{
				PK:                0,
				ID:                "CVE-12345",
				PackageQualifiers: sqlite.ToNullString(nil),
			},
			result: v5.Vulnerability{
				ID: "CVE-12345",
			},
		},
		{
			name: "Empty package_qualifiers array",
			record: &VulnerabilityModel{
				PK:                0,
				ID:                "CVE-919",
				PackageQualifiers: sqlite.NewNullString(`[]`, true),
			},
			result: v5.Vulnerability{
				ID: "CVE-919",
			},
		},
		{
			name: "Single rpmmodularity package qualifier with no module specified",
			record: &VulnerabilityModel{
				PK:                0,
				ID:                "CVE-919",
				PackageQualifiers: sqlite.NewNullString(`[{"kind": "rpm-modularity"}]`, true),
			},
			result: v5.Vulnerability{
				ID: "CVE-919",
				PackageQualifiers: []qualifier.Qualifier{
					rpmmodularity.Qualifier{
						Kind:   "rpm-modularity",
						Module: "",
					},
				},
			},
		},
		{
			name: "Single rpmmodularity package qualifier with empty string module specified",
			record: &VulnerabilityModel{
				PK:                0,
				ID:                "CVE-919",
				PackageQualifiers: sqlite.NewNullString(`[{"kind": "rpm-modularity", "module": ""}]`, true),
			},
			result: v5.Vulnerability{
				ID: "CVE-919",
				PackageQualifiers: []qualifier.Qualifier{
					rpmmodularity.Qualifier{
						Kind:   "rpm-modularity",
						Module: "",
					},
				},
			},
		},
		{
			name: "Single rpmmodularity package qualifier with module specified",
			record: &VulnerabilityModel{
				PK:                0,
				ID:                "CVE-919",
				PackageQualifiers: sqlite.NewNullString(`[{"kind": "rpm-modularity", "module": "x.y.z:2000"}]`, true),
			},
			result: v5.Vulnerability{
				ID: "CVE-919",
				PackageQualifiers: []qualifier.Qualifier{
					rpmmodularity.Qualifier{
						Kind:   "rpm-modularity",
						Module: "x.y.z:2000",
					},
				},
			},
		},
		{
			name: "Single platformcpe package qualifier with cpe specified",
			record: &VulnerabilityModel{
				PK:                0,
				ID:                "CVE-919",
				PackageQualifiers: sqlite.NewNullString(`[{"kind": "platform-cpe", "cpe": "cpe:2.3:o:canonical:ubuntu_linux:19.10:*:*:*:*:*:*:*"}]`, true),
			},
			result: v5.Vulnerability{
				ID: "CVE-919",
				PackageQualifiers: []qualifier.Qualifier{
					platformcpe.Qualifier{
						Kind: "platform-cpe",
						CPE:  "cpe:2.3:o:canonical:ubuntu_linux:19.10:*:*:*:*:*:*:*",
					},
				},
			},
		},
		{
			name: "Single unrecognized package qualifier",
			record: &VulnerabilityModel{
				PK:                0,
				ID:                "CVE-919",
				PackageQualifiers: sqlite.NewNullString(`[{"kind": "unknown", "some-random-slice": [{"x": true}]}]`, true),
			},
			result: v5.Vulnerability{
				ID: "CVE-919",
			},
		},
		{
			name: "Single package qualifier without kind specified",
			record: &VulnerabilityModel{
				PK:                0,
				ID:                "CVE-919",
				PackageQualifiers: sqlite.NewNullString(`[{"some-random-slice": [{"x": true}]}]`, true),
			},
			result: v5.Vulnerability{
				ID: "CVE-919",
			},
		},
		{
			name: "Multiple package qualifiers",
			record: &VulnerabilityModel{
				PK:                0,
				ID:                "CVE-919",
				PackageQualifiers: sqlite.NewNullString(`[{"kind": "rpm-modularity"},{"kind": "rpm-modularity", "module": ""},{"kind": "rpm-modularity", "module": "x.y.z:2000"},{"kind": "unknown", "some-random-slice": [{"x": true}]}]`, true),
			},
			result: v5.Vulnerability{
				ID: "CVE-919",
				PackageQualifiers: []qualifier.Qualifier{
					rpmmodularity.Qualifier{
						Kind:   "rpm-modularity",
						Module: "",
					},
					rpmmodularity.Qualifier{
						Kind:   "rpm-modularity",
						Module: "",
					},
					rpmmodularity.Qualifier{
						Kind:   "rpm-modularity",
						Module: "x.y.z:2000",
					},
				},
			},
		},
	}

	for _, test := range tests {
		t.Run(test.name, func(t *testing.T) {
			result, err := test.record.Inflate()
			assert.NoError(t, err)
			assert.Equal(t, test.result, result)
		})
	}
}
