// 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 genericosv

import (
	"fmt"
	"strings"

	"golang.org/x/vulndb/internal/idstr"
	"golang.org/x/vulndb/internal/osv"
	"golang.org/x/vulndb/internal/proxy"
	"golang.org/x/vulndb/internal/report"
)

var _ report.Source = &Entry{}

// ToReport converts OSV into a Go Report with the given ID.
func (e *Entry) ToReport(*proxy.Client, string) *report.Report {
	r := &report.Report{
		Summary:     report.Summary(e.Summary),
		Description: report.Description(e.Details),
	}
	addAlias := func(alias string) {
		switch {
		case idstr.IsCVE(alias):
			r.CVEs = append(r.CVEs, alias)
		case idstr.IsGHSA(alias):
			r.GHSAs = append(r.GHSAs, alias)
		case idstr.IsGoID(alias):
			// ignore Go IDs
		default:
			r.UnknownAliases = append(r.UnknownAliases, alias)
		}
	}
	addAlias(e.ID)
	for _, alias := range e.Aliases {
		addAlias(alias)
	}

	r.Modules = affectedToModules(e.Affected)

	for _, ref := range e.References {
		r.References = append(r.References, convertRef(ref))
	}

	r.Credits = convertCredits(e.Credits)

	if e.IsWithdrawn() {
		r.Withdrawn = &osv.Time{Time: e.Withdrawn}
	}

	return r
}

func (osv *Entry) SourceID() string {
	return osv.ID
}

func affectedToModules(as []Affected) []*report.Module {
	var modules []*report.Module
	for _, a := range as {
		if a.Package.Ecosystem != EcosystemGo {
			continue
		}

		versions, unsupportedVersions := convertVersions(a.Ranges)
		modules = append(modules, &report.Module{
			Module:              a.Package.Name,
			Versions:            versions,
			UnsupportedVersions: unsupportedVersions,
		})
	}
	return modules
}

func convertVersions(rs []Range) (vs report.Versions, unsupported report.Versions) {
	for _, r := range rs {
		for _, e := range r.Events {
			if e.Introduced != "" || e.Fixed != "" {
				var vr *report.Version
				switch {
				case e.Introduced == "0":
					continue
				case e.Introduced != "":
					vr = report.Introduced(e.Introduced)
				case e.Fixed != "":
					vr = report.Fixed(e.Fixed)
				}
				vs = append(vs, vr)
				continue
			}

			uv := new(report.Version)
			switch {
			case e.LastAffected != "":
				uv.Version = e.LastAffected
				uv.Type = "last_affected"
			case e.Limit != "":
				uv.Version = e.Limit
				uv.Type = "limit"
			default:
				uv.Version = fmt.Sprint(e)
				uv.Type = "unknown"
			}
			unsupported = append(unsupported, uv)
		}
	}
	return vs, unsupported
}

func convertRef(ref Reference) *report.Reference {
	return &report.Reference{
		Type: osv.ReferenceType(ref.Type),
		URL:  ref.URL,
	}
}

func convertCredits(cs []Credit) []string {
	var credits []string
	for _, c := range cs {
		credit := c.Name
		if len(c.Contact) != 0 {
			credit = fmt.Sprintf("%s (%s)", c.Name, strings.Join(c.Contact, ","))
		}
		credits = append(credits, credit)
	}
	return credits
}
