// Copyright 2024 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.

// File copied from github.com/google/osv-scanner@v1.8.0/pkg/models/vulnerability.go
package genericosv

import (
	"encoding/json"
	"time"
)

// Package identifies the affected code library or command provided by the
// package.
//
// See: https://ossf.github.io/osv-schema/#affectedpackage-field
type Package struct {
	Ecosystem Ecosystem `json:"ecosystem"      yaml:"ecosystem"`
	Name      string    `json:"name"           yaml:"name"`
	Purl      string    `json:"purl,omitempty" yaml:"purl,omitempty"`
}

// Event describes a single version that either:
//
//   - Introduces a vulnerability: {"introduced": string}
//   - Fixes a vulnerability: {"fixed": string}
//   - Describes the last known affected version: {"last_affected": string}
//   - Sets an upper limit on the range being described: {"limit": string}
//
// Event instances form part of a “timeline” of status changes for the affected
// package described by the Affected struct.
//
// See: https://ossf.github.io/osv-schema/#affectedrangesevents-fields
type Event struct {
	Introduced   string `json:"introduced,omitempty"    yaml:"introduced,omitempty"`
	Fixed        string `json:"fixed,omitempty"         yaml:"fixed,omitempty"`
	LastAffected string `json:"last_affected,omitempty" yaml:"last_affected,omitempty"`
	Limit        string `json:"limit,omitempty"         yaml:"limit,omitempty"`
}

// Range describes the affected range of given version for a specific package.
//
// See: https://ossf.github.io/osv-schema/#affectedranges-field
type Range struct {
	Type             RangeType              `json:"type"                        yaml:"type"`
	Events           []Event                `json:"events"                      yaml:"events"`
	Repo             string                 `json:"repo,omitempty"              yaml:"repo,omitempty"`
	DatabaseSpecific map[string]interface{} `json:"database_specific,omitempty" yaml:"database_specific,omitempty"`
}

// Severity is used to describe the severity of a vulnerability for an affected
// package using one or more quantitative scoring methods.
//
// See: https://ossf.github.io/osv-schema/#severity-field
type Severity struct {
	Type  SeverityType `json:"type"  yaml:"type"`
	Score string       `json:"score" yaml:"score"`
}

// Affected describes an affected package version, meaning one instance that
// contains the vulnerability.
//
// See: https://ossf.github.io/osv-schema/#affected-fields
type Affected struct {
	Package           Package                `json:"package,omitempty"            yaml:"package,omitempty"`
	Severity          []Severity             `json:"severity,omitempty"           yaml:"severity,omitempty"`
	Ranges            []Range                `json:"ranges,omitempty"             yaml:"ranges,omitempty"`
	Versions          []string               `json:"versions,omitempty"           yaml:"versions,omitempty"`
	DatabaseSpecific  map[string]interface{} `json:"database_specific,omitempty"  yaml:"database_specific,omitempty"`
	EcosystemSpecific map[string]interface{} `json:"ecosystem_specific,omitempty" yaml:"ecosystem_specific,omitempty"`
}

// MarshalJSON implements the json.Marshaler interface.
//
// This method ensures Package is only present if it is not equal to the zero value.
// This is achieved by embedding the Affected struct with a pointer to Package used
// to populate the "package" key in the JSON object.
func (a Affected) MarshalJSON() ([]byte, error) {
	type rawAffected Affected // alias Affected to avoid recursion during Marshal
	type wrapper struct {
		Package *Package `json:"package,omitempty"`
		rawAffected
	}
	raw := wrapper{rawAffected: rawAffected(a)}
	if a.Package == (Package{}) {
		raw.Package = nil
	} else {
		raw.Package = &(a.Package)
	}

	return json.Marshal(raw)
}

// Reference links to additional information, advisories, issue tracker entries,
// and so on about the vulnerability itself.
//
// See: https://ossf.github.io/osv-schema/#references-field
type Reference struct {
	Type ReferenceType `json:"type" yaml:"type"`
	URL  string        `json:"url"  yaml:"url"`
}

// Credit gives credit for the discovery, confirmation, patch, or other events
// in the life cycle of a vulnerability.
//
// See: https://ossf.github.io/osv-schema/#credits-fields
type Credit struct {
	Name    string     `json:"name"              yaml:"name"`
	Type    CreditType `json:"type,omitempty"    yaml:"type,omitempty"`
	Contact []string   `json:"contact,omitempty" yaml:"contact,omitempty"`
}

// Vulnerability is the core Open Source Vulnerability (OSV) data type.
//
// The full documentation for the schema is available at
// https://ossf.github.io/osv-schema.
type Vulnerability struct {
	SchemaVersion string     `json:"schema_version,omitempty"    yaml:"schema_version,omitempty"`
	ID            string     `json:"id"                          yaml:"id"`
	Modified      time.Time  `json:"modified"                    yaml:"modified"`
	Published     time.Time  `json:"published,omitempty"         yaml:"published,omitempty"`
	Withdrawn     time.Time  `json:"withdrawn,omitempty"         yaml:"withdrawn,omitempty"`
	Aliases       []string   `json:"aliases,omitempty"           yaml:"aliases,omitempty"`
	Related       []string   `json:"related,omitempty"           yaml:"related,omitempty"`
	Summary       string     `json:"summary,omitempty"           yaml:"summary,omitempty"`
	Details       string     `json:"details,omitempty"           yaml:"details,omitempty"`
	Affected      []Affected `json:"affected,omitempty"          yaml:"affected,omitempty"`
	// TODO(tatianabradley): There is a bug in Severity unmarshal.
	// We don't use this field, so it is ignored until we fix this.
	Severity         []Severity             `json:"-,omitempty"          yaml:"-,omitempty"`
	References       []Reference            `json:"references,omitempty"        yaml:"references,omitempty"`
	Credits          []Credit               `json:"credits,omitempty"           yaml:"credits,omitempty"`
	DatabaseSpecific map[string]interface{} `json:"database_specific,omitempty" yaml:"database_specific,omitempty"`
}

// MarshalJSON implements the json.Marshaler interface.
//
// This method ensures times all times are formatted correctly according to the schema.
func (v Vulnerability) MarshalJSON() ([]byte, error) {
	type rawVulnerability Vulnerability // alias Vulnerability to avoid recursion during Marshal
	type wrapper struct {
		Modified  string `json:"modified"`
		Published string `json:"published,omitempty"`
		Withdrawn string `json:"withdrawn,omitempty"`
		rawVulnerability
	}
	raw := wrapper{rawVulnerability: rawVulnerability(v)}
	raw.Modified = v.Modified.UTC().Format(time.RFC3339)
	if !v.Published.IsZero() {
		raw.Published = v.Published.UTC().Format(time.RFC3339)
	}
	if !v.Withdrawn.IsZero() {
		raw.Withdrawn = v.Withdrawn.UTC().Format(time.RFC3339)
	}

	return json.Marshal(raw)
}

// MarshalYAML implements the yaml.Marshaler interface.
//
// This method ensures times all times are formatted correctly.
func (v Vulnerability) MarshalYAML() (interface{}, error) {
	type rawVulnerability Vulnerability // alias Vulnerability to avoid recursion during Marshal
	raw := rawVulnerability(v)
	if !v.Modified.IsZero() {
		raw.Modified = v.Modified.UTC()
	}
	if !v.Published.IsZero() {
		raw.Published = v.Published.UTC()
	}
	if !v.Withdrawn.IsZero() {
		raw.Withdrawn = v.Withdrawn.UTC()
	}

	return raw, nil
}
