

package reason

import (
	"regexp"

	"k8s.io/klog/v2"
)

// match matches a known issue within minikube
type match struct {
	// Inherit ID, ExitCode, and Style from reason.Kind
	Kind

	// Regexp is which regular expression this issue matches
	Regexp *regexp.Regexp
	// Operating systems this error is specific to
	GOOS []string
}

func knownIssues() []match {
	ps := []match{}
	// This is intentionally in dependency order
	ps = append(ps, programIssues...)
	ps = append(ps, resourceIssues...)
	ps = append(ps, hostIssues...)
	ps = append(ps, providerIssues...)
	ps = append(ps, driverIssues...)
	ps = append(ps, localNetworkIssues...)
	ps = append(ps, internetIssues...)
	ps = append(ps, guestIssues...)
	ps = append(ps, runtimeIssues...)
	ps = append(ps, controlPlaneIssues...)
	ps = append(ps, serviceIssues...)
	return ps
}

// MatchKnownIssue returns a known issue from an error on an OS
func MatchKnownIssue(r Kind, err error, goos string) *Kind {
	// The kind passed in has specified that it should not be rematched
	if r.NoMatch {
		return nil
	}

	var genericMatch *Kind

	for _, ki := range knownIssues() {
		ki := ki
		if ki.Regexp == nil {
			klog.Errorf("known issue has no regexp: %+v", ki)
			continue
		}

		if !ki.Regexp.MatchString(err.Error()) {
			continue
		}

		// Does this match require an OS matchup?
		if len(ki.GOOS) > 0 {
			for _, o := range ki.GOOS {
				if o == goos {
					return &ki.Kind
				}
			}
		}
		if genericMatch == nil {
			genericMatch = &ki.Kind
		}
	}

	return genericMatch
}
