// 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 database provides functionality for reading, writing, and
// validating Go vulnerability databases according to the v1 schema.
package database

import (
	"encoding/json"
	"fmt"

	"golang.org/x/exp/maps"
	"golang.org/x/exp/slices"
	"golang.org/x/vulndb/internal/osv"
)

// Database represents a Go Vulnerability Database in the v1 schema.
type Database struct {
	// DB represents the index/db.json endpoint.
	DB DBMeta
	// Modules represents the index/modules.json endpoint.
	Modules ModulesIndex
	// Vulns represents the index/vulns.json endpoint.
	Vulns VulnsIndex
	// Entries represents the ID/GO-YYYY-XXXX.json endpoints.
	Entries []osv.Entry
}

// DBMeta contains metadata about the database itself.
type DBMeta struct {
	// Modified is the time the database was last modified, calculated
	// as the most recent time any single OSV entry was modified.
	Modified osv.Time `json:"modified"`
}

// ModulesIndex is a map from module paths to module metadata.
// It marshals into and unmarshals from the format published in
// index/modules.json, which is a JSON array of objects.
type ModulesIndex map[string]*Module

func (m *ModulesIndex) UnmarshalJSON(data []byte) error {
	var modules []*Module
	if err := json.Unmarshal(data, &modules); err != nil {
		return err
	}
	for _, module := range modules {
		path := module.Path
		if _, ok := (*m)[path]; ok {
			return fmt.Errorf("module %q appears twice in modules.json", path)
		}
		(*m)[path] = module
	}
	return nil
}

func (m ModulesIndex) MarshalJSON() ([]byte, error) {
	modules := maps.Values(m)
	slices.SortStableFunc(modules, func(m1, m2 *Module) int {
		switch {
		case m1.Path < m2.Path:
			return -1
		case m1.Path > m2.Path:
			return 1
		default:
			return 0
		}
	})
	for _, module := range modules {
		slices.SortStableFunc(module.Vulns, func(v1, v2 ModuleVuln) int {
			switch {
			case v1.ID < v2.ID:
				return -1
			case v1.ID > v2.ID:
				return 1
			default:
				return 0
			}
		})
	}
	return json.Marshal(modules)
}

// Module contains metadata about a Go module that has one
// or more vulnerabilities in the database.
type Module struct {
	// Path is the module path.
	Path string `json:"path"`
	// Vulns is a list of vulnerabilities that affect this module.
	Vulns []ModuleVuln `json:"vulns"`
}

// ModuleVuln contains metadata about a vulnerability that affects
// a certain module (as used by the ModulesIndex).
type ModuleVuln struct {
	// ID is a unique identifier for the vulnerability.
	// The Go vulnerability database issues IDs of the form
	// GO-<YEAR>-<ENTRYID>.
	ID string `json:"id"`
	// Modified is the time the vuln was last modified.
	Modified osv.Time `json:"modified"`
	// Fixed is the latest version that introduces a fix for the
	// vulnerability, in SemVer 2.0.0 format, with no leading "v" prefix.
	// (This is technically the earliest version V such that the
	// vulnerability does not occur in any version later than V.)
	//
	// This field can be used to determine if a version is definitely
	// not affected by a vulnerability (if the version is greater than
	// or equal to the fixed version), but the full OSV entry must
	// be downloaded to determine if a version less than the fixed
	// version is affected.
	//
	// This field is optional, and should be empty if there is no
	// known fixed version.
	//
	// Example:
	// Suppose a vulnerability is present in all versions
	// up to (not including) version 1.5.0, is re-introduced in version
	// 2.0.0, and fixed again in version 2.4.0. The "Fixed" version
	// would be 2.4.0.
	// The fixed version tells us that any version greater than or equal
	// to 2.4.0 is not affected, but we would need to look at the OSV
	// entry to determine if any version less than 2.4.0 was affected.
	Fixed string `json:"fixed,omitempty"`
}

// VulnsIndex is a map from vulnerability IDs to vulnerability metadata.
// It marshals into and unmarshals from the format published in
// index/vulns.json, which is a JSON array of objects.
type VulnsIndex map[string]*Vuln

func (v VulnsIndex) MarshalJSON() ([]byte, error) {
	vulns := maps.Values(v)
	slices.SortStableFunc(vulns, func(v1, v2 *Vuln) int {
		switch {
		case v1.ID < v2.ID:
			return -1
		case v1.ID > v2.ID:
			return 1
		default:
			return 0
		}
	})
	return json.Marshal(vulns)
}

func (v *VulnsIndex) UnmarshalJSON(data []byte) error {
	var vulns []*Vuln
	if err := json.Unmarshal(data, &vulns); err != nil {
		return err
	}
	for _, vuln := range vulns {
		id := vuln.ID
		if _, ok := (*v)[id]; ok {
			return fmt.Errorf("id %q appears twice in vulns.json", id)
		}
		(*v)[id] = vuln
	}
	return nil
}

// Vuln contains metadata about a vulnerability in the database,
// as used by the VulnsIndex.
type Vuln struct {
	// ID is a unique identifier for the vulnerability.
	// The Go vulnerability database issues IDs of the form
	// GO-<YEAR>-<ENTRYID>.
	ID string `json:"id"`
	// Modified is the time the vulnerability was last modified.
	Modified osv.Time `json:"modified"`
	// Aliases is a list of IDs for the same vulnerability in other
	// databases.
	Aliases []string `json:"aliases,omitempty"`
}
