package filter

import (
	"testing"

	"github.com/ckotzbauer/vulnerability-operator/internal/vuln"
	"github.com/ckotzbauer/vulnerability-operator/internal/vuln/kubernetes"
	"github.com/stretchr/testify/assert"
)

type testData struct {
	config   FilterConfig
	vulnList []vuln.Vulnerability
	audited  []vuln.Vulnerability
	found    []vuln.Vulnerability
}

var libcryptoVuln = vuln.Vulnerability{ID: "CVE-2021-4160", Package: "libcrypto1.1", Severity: "Medium", Type: "apk", ImageID: "alpine:3.17", Containers: []kubernetes.ContainerInfo{{Namespace: "monitoring", OwnerName: "grafana", OwnerKind: "Deployment", PodName: "grafana-6d54bf9447-t7dfc"}}}
var libcryptoVulnPod = vuln.Vulnerability{ID: "CVE-2021-4160", Package: "libcrypto1.1", Severity: "Medium", Type: "apk", ImageID: "alpine:3.17", Containers: []kubernetes.ContainerInfo{{Namespace: "monitoring", OwnerName: "grafana", OwnerKind: "Pod", PodName: "grafana-6d54bf9447-t7dfc"}}}
var libcryptoVulnMultiDeployment = vuln.Vulnerability{ID: "CVE-2023-0215", Package: "libcrypto3", Severity: "High", Type: "apk", ImageID: "alpine:3.17", Containers: []kubernetes.ContainerInfo{{Namespace: "monitoring", OwnerName: "grafana", OwnerKind: "Deployment", PodName: "grafana-6d54bf9447-t7dfc"}, {Namespace: "monitoring", OwnerName: "kube-state-metrics", OwnerKind: "Deployment", PodName: "kube-state-metrics-6d54bf9447-t7dfc"}}}

func TestFilterVulnerabilities(t *testing.T) {
	tests := []testData{
		{
			config:   FilterConfig{},
			vulnList: []vuln.Vulnerability{libcryptoVuln},
			audited:  []vuln.Vulnerability{},
			found: []vuln.Vulnerability{
				libcryptoVuln,
			},
		},
		{
			config:   FilterConfig{Ignore: []VulnerabilityFilter{{Vulnerability: "CVE-2021-4160"}}},
			vulnList: []vuln.Vulnerability{libcryptoVuln},
			audited:  []vuln.Vulnerability{},
			found:    []vuln.Vulnerability{},
		},
		{
			config:   FilterConfig{Audit: []VulnerabilityFilter{{Vulnerability: "CVE-2021-4160"}}},
			vulnList: []vuln.Vulnerability{libcryptoVuln},
			audited: []vuln.Vulnerability{
				libcryptoVuln,
			},
			found: []vuln.Vulnerability{},
		},
		{
			config:   FilterConfig{Audit: []VulnerabilityFilter{{Vulnerability: "CVE-2021-4161"}}},
			vulnList: []vuln.Vulnerability{libcryptoVuln},
			audited:  []vuln.Vulnerability{},
			found: []vuln.Vulnerability{
				libcryptoVuln,
			},
		},
		{
			config:   FilterConfig{Audit: []VulnerabilityFilter{{Vulnerability: "CVE-2021-4160", Context: []FilterContext{{Image: "alpine:3.17"}}}}},
			vulnList: []vuln.Vulnerability{libcryptoVuln},
			audited: []vuln.Vulnerability{
				libcryptoVuln,
			},
			found: []vuln.Vulnerability{},
		},
		{
			config:   FilterConfig{Audit: []VulnerabilityFilter{{Vulnerability: "CVE-2021-4160", Context: []FilterContext{{Image: "alpine:3.*"}}}}},
			vulnList: []vuln.Vulnerability{libcryptoVuln},
			audited: []vuln.Vulnerability{
				libcryptoVuln,
			},
			found: []vuln.Vulnerability{},
		},
		{
			config:   FilterConfig{Audit: []VulnerabilityFilter{{Vulnerability: "CVE-2021-4160", Context: []FilterContext{{Image: "alpine:2.*"}}}}},
			vulnList: []vuln.Vulnerability{libcryptoVuln},
			audited:  []vuln.Vulnerability{},
			found: []vuln.Vulnerability{
				libcryptoVuln,
			},
		},
		{
			config:   FilterConfig{Audit: []VulnerabilityFilter{{Package: "libcrypto1.1"}}},
			vulnList: []vuln.Vulnerability{libcryptoVuln},
			audited: []vuln.Vulnerability{
				libcryptoVuln,
			},
			found: []vuln.Vulnerability{},
		},
		{
			config:   FilterConfig{Audit: []VulnerabilityFilter{{Package: "libtls"}}},
			vulnList: []vuln.Vulnerability{libcryptoVuln},
			audited:  []vuln.Vulnerability{},
			found: []vuln.Vulnerability{
				libcryptoVuln,
			},
		},
		{
			config:   FilterConfig{Audit: []VulnerabilityFilter{{Vulnerability: "CVE-2021-4160", Context: []FilterContext{{Namespace: "monitoring"}}}}},
			vulnList: []vuln.Vulnerability{libcryptoVuln},
			audited: []vuln.Vulnerability{
				libcryptoVuln,
			},
			found: []vuln.Vulnerability{},
		},
		{
			config:   FilterConfig{Audit: []VulnerabilityFilter{{Vulnerability: "CVE-2021-4160", Context: []FilterContext{{Namespace: "*toring"}}}}},
			vulnList: []vuln.Vulnerability{libcryptoVuln},
			audited: []vuln.Vulnerability{
				libcryptoVuln,
			},
			found: []vuln.Vulnerability{},
		},
		{
			config:   FilterConfig{Audit: []VulnerabilityFilter{{Vulnerability: "CVE-2021-4160", Context: []FilterContext{{Namespace: "monitoring", Name: "prometheus"}}}}},
			vulnList: []vuln.Vulnerability{libcryptoVuln},
			audited:  []vuln.Vulnerability{},
			found: []vuln.Vulnerability{
				libcryptoVuln,
			},
		},
		{
			config:   FilterConfig{Audit: []VulnerabilityFilter{{Vulnerability: "CVE-2021-4160", Context: []FilterContext{{Namespace: "monitoring", Name: "grafana"}}}}},
			vulnList: []vuln.Vulnerability{libcryptoVuln},
			audited: []vuln.Vulnerability{
				libcryptoVuln,
			},
			found: []vuln.Vulnerability{},
		},
		{
			config:   FilterConfig{Audit: []VulnerabilityFilter{{Vulnerability: "CVE-2021-4160", Context: []FilterContext{{Namespace: "monitoring", Kind: "Pod"}}}}},
			vulnList: []vuln.Vulnerability{libcryptoVuln},
			audited:  []vuln.Vulnerability{},
			found: []vuln.Vulnerability{
				libcryptoVuln,
			},
		},
		{
			config:   FilterConfig{Audit: []VulnerabilityFilter{{Vulnerability: "CVE-2021-4160", Context: []FilterContext{{Namespace: "monitoring", Kind: "Deployment"}}}}},
			vulnList: []vuln.Vulnerability{libcryptoVuln},
			audited: []vuln.Vulnerability{
				libcryptoVuln,
			},
			found: []vuln.Vulnerability{},
		},
		{
			config:   FilterConfig{Audit: []VulnerabilityFilter{{Vulnerability: "CVE-2021-4160", Context: []FilterContext{{Namespace: "monitoring", Kind: "Pod"}}}}},
			vulnList: []vuln.Vulnerability{libcryptoVulnPod},
			audited: []vuln.Vulnerability{
				libcryptoVulnPod,
			},
			found: []vuln.Vulnerability{},
		},
		{
			config:   FilterConfig{Audit: []VulnerabilityFilter{{Vulnerability: "CVE-2021-4160", Context: []FilterContext{{Namespace: "monitoring", Kind: "Pod", Name: "grafana-6d54bf9447*"}}}}},
			vulnList: []vuln.Vulnerability{libcryptoVulnPod},
			audited: []vuln.Vulnerability{
				libcryptoVulnPod,
			},
			found: []vuln.Vulnerability{},
		},
		{
			config:   FilterConfig{Audit: []VulnerabilityFilter{{Vulnerability: "CVE-2021-4160", Context: []FilterContext{{Namespace: "monitoring", Kind: "Pod", Name: "grafana-6d54bf9447"}}}}},
			vulnList: []vuln.Vulnerability{libcryptoVulnPod},
			audited:  []vuln.Vulnerability{},
			found: []vuln.Vulnerability{
				libcryptoVulnPod,
			},
		},
		{
			config:   FilterConfig{Audit: []VulnerabilityFilter{{Vulnerability: "CVE-2021-4160", Context: []FilterContext{{Namespace: "monitoring", Kind: "Pod", Name: "grafana-123456789*"}}}}},
			vulnList: []vuln.Vulnerability{libcryptoVulnPod},
			audited:  []vuln.Vulnerability{},
			found: []vuln.Vulnerability{
				libcryptoVulnPod,
			},
		},
		{
			config:   FilterConfig{Audit: []VulnerabilityFilter{{Vulnerability: "CVE-2021-4160", Context: []FilterContext{{Namespace: "monitoring", Kind: "Deployment", Name: "grafana-123456789*"}}}}},
			vulnList: []vuln.Vulnerability{libcryptoVulnPod},
			audited:  []vuln.Vulnerability{},
			found: []vuln.Vulnerability{
				libcryptoVulnPod,
			},
		},

		{
			config:   FilterConfig{Ignore: []VulnerabilityFilter{{Vulnerability: "CVE-2021-4161"}}},
			vulnList: []vuln.Vulnerability{libcryptoVuln},
			audited:  []vuln.Vulnerability{},
			found: []vuln.Vulnerability{
				libcryptoVuln,
			},
		},
		{
			config:   FilterConfig{Ignore: []VulnerabilityFilter{{Vulnerability: "CVE-2021-4160", Context: []FilterContext{{Image: "alpine:3.17"}}}}},
			vulnList: []vuln.Vulnerability{libcryptoVuln},
			audited:  []vuln.Vulnerability{},
			found:    []vuln.Vulnerability{},
		},
		{
			config:   FilterConfig{Ignore: []VulnerabilityFilter{{Vulnerability: "CVE-2021-4160", Context: []FilterContext{{Image: "alpine:3.*"}}}}},
			vulnList: []vuln.Vulnerability{libcryptoVuln},
			audited:  []vuln.Vulnerability{},
			found:    []vuln.Vulnerability{},
		},
		{
			config:   FilterConfig{Ignore: []VulnerabilityFilter{{Vulnerability: "CVE-2021-4160", Context: []FilterContext{{Image: "alpine:2.*"}}}}},
			vulnList: []vuln.Vulnerability{libcryptoVuln},
			audited:  []vuln.Vulnerability{},
			found: []vuln.Vulnerability{
				libcryptoVuln,
			},
		},
		{
			config:   FilterConfig{Ignore: []VulnerabilityFilter{{Package: "libcrypto1.1"}}},
			vulnList: []vuln.Vulnerability{libcryptoVuln},
			audited:  []vuln.Vulnerability{},
			found:    []vuln.Vulnerability{},
		},
		{
			config:   FilterConfig{Ignore: []VulnerabilityFilter{{Package: "libtls"}}},
			vulnList: []vuln.Vulnerability{libcryptoVuln},
			audited:  []vuln.Vulnerability{},
			found: []vuln.Vulnerability{
				libcryptoVuln,
			},
		},
		{
			config:   FilterConfig{Ignore: []VulnerabilityFilter{{Vulnerability: "CVE-2021-4160", Context: []FilterContext{{Namespace: "monitoring"}}}}},
			vulnList: []vuln.Vulnerability{libcryptoVuln},
			audited:  []vuln.Vulnerability{},
			found:    []vuln.Vulnerability{},
		},
		{
			config:   FilterConfig{Ignore: []VulnerabilityFilter{{Vulnerability: "CVE-2021-4160", Context: []FilterContext{{Namespace: "*toring"}}}}},
			vulnList: []vuln.Vulnerability{libcryptoVuln},
			audited:  []vuln.Vulnerability{},
			found:    []vuln.Vulnerability{},
		},
		{
			config:   FilterConfig{Ignore: []VulnerabilityFilter{{Vulnerability: "CVE-2021-4160", Context: []FilterContext{{Namespace: "monitoring", Name: "prometheus"}}}}},
			vulnList: []vuln.Vulnerability{libcryptoVuln},
			audited:  []vuln.Vulnerability{},
			found: []vuln.Vulnerability{
				libcryptoVuln,
			},
		},
		{
			config:   FilterConfig{Ignore: []VulnerabilityFilter{{Vulnerability: "CVE-2021-4160", Context: []FilterContext{{Namespace: "monitoring", Name: "grafana"}}}}},
			vulnList: []vuln.Vulnerability{libcryptoVuln},
			audited:  []vuln.Vulnerability{},
			found:    []vuln.Vulnerability{},
		},
		{
			config:   FilterConfig{Ignore: []VulnerabilityFilter{{Vulnerability: "CVE-2021-4160", Context: []FilterContext{{Namespace: "monitoring", Kind: "Pod"}}}}},
			vulnList: []vuln.Vulnerability{libcryptoVuln},
			audited:  []vuln.Vulnerability{},
			found: []vuln.Vulnerability{
				libcryptoVuln,
			},
		},
		{
			config:   FilterConfig{Ignore: []VulnerabilityFilter{{Vulnerability: "CVE-2021-4160", Context: []FilterContext{{Namespace: "monitoring", Kind: "Deployment"}}}}},
			vulnList: []vuln.Vulnerability{libcryptoVuln},
			audited:  []vuln.Vulnerability{},
			found:    []vuln.Vulnerability{},
		},
		{
			config:   FilterConfig{Ignore: []VulnerabilityFilter{{Vulnerability: "CVE-2021-4160", Context: []FilterContext{{Namespace: "monitoring", Kind: "Pod"}}}}},
			vulnList: []vuln.Vulnerability{libcryptoVulnPod},
			audited:  []vuln.Vulnerability{},
			found:    []vuln.Vulnerability{},
		},
		{
			config:   FilterConfig{Ignore: []VulnerabilityFilter{{Vulnerability: "CVE-2021-4160", Context: []FilterContext{{Namespace: "monitoring", Kind: "Pod", Name: "grafana-6d54bf9447*"}}}}},
			vulnList: []vuln.Vulnerability{libcryptoVulnPod},
			audited:  []vuln.Vulnerability{},
			found:    []vuln.Vulnerability{},
		},
		{
			config:   FilterConfig{Ignore: []VulnerabilityFilter{{Vulnerability: "CVE-2021-4160", Context: []FilterContext{{Namespace: "monitoring", Kind: "Pod", Name: "grafana-6d54bf9447"}}}}},
			vulnList: []vuln.Vulnerability{libcryptoVulnPod},
			audited:  []vuln.Vulnerability{},
			found: []vuln.Vulnerability{
				libcryptoVulnPod,
			},
		},
		{
			config:   FilterConfig{Ignore: []VulnerabilityFilter{{Vulnerability: "CVE-2021-4160", Context: []FilterContext{{Namespace: "monitoring", Kind: "Pod", Name: "grafana-123456789*"}}}}},
			vulnList: []vuln.Vulnerability{libcryptoVulnPod},
			audited:  []vuln.Vulnerability{},
			found: []vuln.Vulnerability{
				libcryptoVulnPod,
			},
		},
		{
			config:   FilterConfig{Ignore: []VulnerabilityFilter{{Vulnerability: "CVE-2021-4160", Context: []FilterContext{{Namespace: "monitoring", Kind: "Deployment", Name: "grafana-123456789*"}}}}},
			vulnList: []vuln.Vulnerability{libcryptoVulnPod},
			audited:  []vuln.Vulnerability{},
			found: []vuln.Vulnerability{
				libcryptoVulnPod,
			},
		},
		{
			config:   FilterConfig{Audit: []VulnerabilityFilter{{Vulnerability: "CVE-2023-0215", Context: []FilterContext{{Namespace: "monitoring", Kind: "Deployment", Name: "grafana"}}}}},
			vulnList: []vuln.Vulnerability{libcryptoVulnMultiDeployment},
			audited:  []vuln.Vulnerability{{ID: "CVE-2023-0215", Package: "libcrypto3", Severity: "High", Type: "apk", ImageID: "alpine:3.17", Containers: []kubernetes.ContainerInfo{{Namespace: "monitoring", OwnerName: "grafana", OwnerKind: "Deployment", PodName: "grafana-6d54bf9447-t7dfc"}}}},
			found:    []vuln.Vulnerability{{ID: "CVE-2023-0215", Package: "libcrypto3", Severity: "High", Type: "apk", ImageID: "alpine:3.17", Containers: []kubernetes.ContainerInfo{{Namespace: "monitoring", OwnerName: "kube-state-metrics", OwnerKind: "Deployment", PodName: "kube-state-metrics-6d54bf9447-t7dfc"}}}},
		},
		{
			config:   FilterConfig{Ignore: []VulnerabilityFilter{{Vulnerability: "CVE-2023-0215", Context: []FilterContext{{Namespace: "monitoring", Kind: "Deployment", Name: "grafana"}}}}},
			vulnList: []vuln.Vulnerability{libcryptoVulnMultiDeployment},
			audited:  []vuln.Vulnerability{},
			found:    []vuln.Vulnerability{{ID: "CVE-2023-0215", Package: "libcrypto3", Severity: "High", Type: "apk", ImageID: "alpine:3.17", Containers: []kubernetes.ContainerInfo{{Namespace: "monitoring", OwnerName: "kube-state-metrics", OwnerKind: "Deployment", PodName: "kube-state-metrics-6d54bf9447-t7dfc"}}}},
		},
		{
			config:   FilterConfig{Ignore: []VulnerabilityFilter{{Vulnerability: "CVE-2023-0215", Context: []FilterContext{{Namespace: "monitoring", Kind: "Deployment", Name: "kube-state-metrics"}}}}, Audit: []VulnerabilityFilter{{Vulnerability: "CVE-2023-0215", Context: []FilterContext{{Namespace: "monitoring", Kind: "Deployment", Name: "grafana"}}}}},
			vulnList: []vuln.Vulnerability{libcryptoVulnMultiDeployment},
			audited:  []vuln.Vulnerability{{ID: "CVE-2023-0215", Package: "libcrypto3", Severity: "High", Type: "apk", ImageID: "alpine:3.17", Containers: []kubernetes.ContainerInfo{{Namespace: "monitoring", OwnerName: "grafana", OwnerKind: "Deployment", PodName: "grafana-6d54bf9447-t7dfc"}}}},
			found:    []vuln.Vulnerability{},
		},
		{
			config:   FilterConfig{Audit: []VulnerabilityFilter{{Vulnerability: "CVE-2023-0215", Context: []FilterContext{{Namespace: "monitoring", Kind: "Deployment", Name: "grafana"}, {Namespace: "monitoring", Kind: "Deployment", Name: "kube-state-metrics"}}}}},
			vulnList: []vuln.Vulnerability{libcryptoVulnMultiDeployment},
			audited:  []vuln.Vulnerability{{ID: "CVE-2023-0215", Package: "libcrypto3", Severity: "High", Type: "apk", ImageID: "alpine:3.17", Containers: []kubernetes.ContainerInfo{{Namespace: "monitoring", OwnerName: "grafana", OwnerKind: "Deployment", PodName: "grafana-6d54bf9447-t7dfc"}, {Namespace: "monitoring", OwnerName: "kube-state-metrics", OwnerKind: "Deployment", PodName: "kube-state-metrics-6d54bf9447-t7dfc"}}}},
			found:    []vuln.Vulnerability{},
		},
		{
			config:   FilterConfig{Audit: []VulnerabilityFilter{{Vulnerability: "CVE-2023-0215", Context: []FilterContext{{Namespace: "monitoring", Kind: "Deployment", Name: "grafana"}}}, {Vulnerability: "CVE-2023-0215", Context: []FilterContext{{Namespace: "monitoring", Kind: "Deployment", Name: "kube-state-metrics"}}}}},
			vulnList: []vuln.Vulnerability{libcryptoVulnMultiDeployment},
			audited:  []vuln.Vulnerability{{ID: "CVE-2023-0215", Package: "libcrypto3", Severity: "High", Type: "apk", ImageID: "alpine:3.17", Containers: []kubernetes.ContainerInfo{{Namespace: "monitoring", OwnerName: "grafana", OwnerKind: "Deployment", PodName: "grafana-6d54bf9447-t7dfc"}, {Namespace: "monitoring", OwnerName: "kube-state-metrics", OwnerKind: "Deployment", PodName: "kube-state-metrics-6d54bf9447-t7dfc"}}}},
			found:    []vuln.Vulnerability{},
		},
		{
			config:   FilterConfig{Audit: []VulnerabilityFilter{{Vulnerability: "CVE-2023-0215", Context: []FilterContext{{Namespace: "monitoring", Kind: "Deployment", Name: "grafana"}}}, {Vulnerability: "CVE-2023-0215", Context: []FilterContext{}}}},
			vulnList: []vuln.Vulnerability{libcryptoVulnMultiDeployment},
			audited:  []vuln.Vulnerability{{ID: "CVE-2023-0215", Package: "libcrypto3", Severity: "High", Type: "apk", ImageID: "alpine:3.17", Containers: []kubernetes.ContainerInfo{{Namespace: "monitoring", OwnerName: "grafana", OwnerKind: "Deployment", PodName: "grafana-6d54bf9447-t7dfc"}, {Namespace: "monitoring", OwnerName: "kube-state-metrics", OwnerKind: "Deployment", PodName: "kube-state-metrics-6d54bf9447-t7dfc"}}}},
			found:    []vuln.Vulnerability{},
		},
	}

	for _, v := range tests {
		t.Run("", func(t *testing.T) {
			engine := NewFilterEngine(&v.config)
			found, audited := engine.FilterVulnerabilities(v.vulnList)
			assert.ElementsMatch(t, found, v.found)
			assert.ElementsMatch(t, audited, v.audited)
		})
	}
}
