// Copyright 2021 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 ghsa

import (
	"context"
	"fmt"
	"strings"

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

var _ report.Source = &SecurityAdvisory{}

func (sa *SecurityAdvisory) ToReport(_ *proxy.Client, modulePath string) *report.Report {
	return ghsaToReport(sa, modulePath)
}

func (sa *SecurityAdvisory) SourceID() string {
	return sa.ID
}

var _ report.Fetcher = &Client{}

func (c *Client) Fetch(ctx context.Context, id string) (report.Source, error) {
	return c.FetchGHSA(ctx, id)
}

// ghsaToReport creates a Report struct from a given GHSA SecurityAdvisory and modulePath.
func ghsaToReport(sa *SecurityAdvisory, modulePath string) *report.Report {
	r := &report.Report{
		Summary:     report.Summary(sa.Summary),
		Description: report.Description(sa.Description),
	}
	var cves, ghsas []string
	for _, id := range sa.Identifiers {
		switch id.Type {
		case "CVE":
			cves = append(cves, id.Value)
		case "GHSA":
			ghsas = append(ghsas, id.Value)
		}
	}
	for _, ref := range sa.References {
		r.References = append(r.References, report.ReferenceFromUrl(ref.URL))
	}
	r.CVEs = cves
	r.GHSAs = ghsas
	for _, v := range sa.Vulns {
		if modulePath == "" {
			modulePath = v.Package
		}
		m := &report.Module{
			Module:   modulePath,
			Versions: versions(v.EarliestFixedVersion, v.VulnerableVersionRange),
			Packages: []*report.Package{{
				Package: v.Package,
			}},
		}
		r.Modules = append(r.Modules, m)
	}
	return r
}

// versions extracts the versions in which a vulnerability was introduced and
// fixed from a Github Security Advisory's EarliestFixedVersion and
// VulnerableVersionRange fields, and wraps them in a []VersionRange.
//
// If the vulnRange cannot be parsed, or the earliestFixed and vulnRange are
// incompatible, populate the relevant fields with a TODO for a human to handle.
func versions(earliestFixed, vulnRange string) report.Versions {
	// Don't try to be fully general here. Handle the common cases (which, as of
	// March 2022, are the only cases), and let a person handle the others.
	items, err := parseVulnRange(vulnRange)
	if err != nil {
		return report.Versions{
			report.Introduced(fmt.Sprintf("TODO (got error %q)", err)),
		}
	}

	var intro, fixed string

	// Most common case: a single "<" item with a version that matches earliestFixed.
	if len(items) == 1 && items[0].op == "<" && items[0].version == earliestFixed {
		intro = "0.0.0"
		fixed = earliestFixed
	}

	// Two items, one >= and one <, with the latter matching earliestFixed.
	if len(items) == 2 && items[0].op == ">=" && items[1].op == "<" && items[1].version == earliestFixed {
		intro = items[0].version
		fixed = earliestFixed
	}

	// A single "<=" item with no fixed version.
	if len(items) == 1 && items[0].op == "<=" && earliestFixed == "" {
		intro = "0.0.0"
	}

	if intro == "" {
		intro = fmt.Sprintf("TODO (earliest fixed %q, vuln range %q)", earliestFixed, vulnRange)
	}

	// Unset intro if vuln was always present.
	if intro == "0.0.0" {
		intro = ""
	}

	var result report.Versions
	if intro != "" {
		result = append(result, report.Introduced(intro))
	}
	if fixed != "" {
		result = append(result, report.Fixed(fixed))
	}
	return result
}

type vulnRangeItem struct {
	op, version string
}

// parseVulnRange splits the contents of a GitHub Security Advisory's
// VulnerableVersionRange field into separate items.
func parseVulnRange(s string) ([]vulnRangeItem, error) {
	// A GHSA vuln range is a comma-separated list of items of the form "OP VERSION"
	// where OP is one of "<", ">", "<=" or ">=" and VERSION is a semantic
	// version.
	var items []vulnRangeItem
	parts := strings.Split(s, ",")
	for _, p := range parts {
		p = strings.TrimSpace(p)
		if p == "" {
			continue
		}
		before, after, found := strings.Cut(p, " ")
		if !found {
			return nil, fmt.Errorf("invalid vuln range item %q", p)
		}
		items = append(items, vulnRangeItem{strings.TrimSpace(before), strings.TrimSpace(after)})
	}
	return items, nil
}
