package flag_test

import (
	"testing"

	"github.com/spf13/viper"
	"github.com/stretchr/testify/assert"
	"go.uber.org/zap"
	"go.uber.org/zap/zaptest/observer"

	"github.com/aquasecurity/trivy/pkg/flag"
	"github.com/aquasecurity/trivy/pkg/log"
	"github.com/aquasecurity/trivy/pkg/types"
)

func TestVulnerabilityFlagGroup_ToOptions(t *testing.T) {
	type fields struct {
		vulnType string
	}
	tests := []struct {
		name     string
		args     []string
		fields   fields
		want     flag.VulnerabilityOptions
		wantLogs []string
	}{
		{
			name: "happy path for OS vulnerabilities",
			args: []string{"alpine:latest"},
			fields: fields{
				vulnType: "os",
			},
			want: flag.VulnerabilityOptions{
				VulnType: []string{types.VulnTypeOS},
			},
		},
		{
			name: "happy path for library vulnerabilities",
			args: []string{"alpine:latest"},
			fields: fields{
				vulnType: "library",
			},
			want: flag.VulnerabilityOptions{
				VulnType: []string{types.VulnTypeLibrary},
			},
		},
		{
			name: "wrong vuln type",
			fields: fields{
				vulnType: "os,nonevuln",
			},
			want: flag.VulnerabilityOptions{
				VulnType: []string{types.VulnTypeOS},
			},
			wantLogs: []string{
				`unknown vulnerability type: nonevuln`,
			},
		},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			level := zap.WarnLevel

			core, obs := observer.New(level)
			log.Logger = zap.New(core).Sugar()

			viper.Set(flag.VulnTypeFlag.ConfigName, tt.fields.vulnType)

			// Assert options
			f := &flag.VulnerabilityFlagGroup{
				VulnType: &flag.VulnTypeFlag,
			}

			got := f.ToOptions()
			assert.Equalf(t, tt.want, got, "ToOptions()")

			// Assert log messages
			var gotMessages []string
			for _, entry := range obs.AllUntimed() {
				gotMessages = append(gotMessages, entry.Message)
			}
			assert.Equal(t, tt.wantLogs, gotMessages, tt.name)
		})

	}
}
