// 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 store supports permanent data storage for the vuln worker.
package store

import (
	"context"
	"errors"
	"fmt"
	"time"

	"github.com/go-git/go-git/v5/plumbing/object"
	"golang.org/x/vulndb/internal/cve4"
	"golang.org/x/vulndb/internal/ghsa"
	"golang.org/x/vulndb/internal/report"
)

// A CVE4Record contains information about a v4 CVE.
type CVE4Record struct {
	// ID is the CVE ID, which is the same as the filename base. E.g. "CVE-2020-0034".
	ID string
	// Path is the path to the CVE file in the repo.
	Path string
	// Blobhash is the hash of the CVE's blob in repo, for quick change detection.
	BlobHash string
	// CommitHash is the commit of the cvelist repo from which this information came.
	CommitHash string
	// CommitTime is the time of the above commit.
	// If zero, it has not been populated.
	CommitTime time.Time
	// CVEState is the value of the metadata.STATE field.
	CVEState string
	// TriageState is the state of our triage processing on the CVE.
	TriageState TriageState
	// TriageStateReason is an explanation of TriageState.
	TriageStateReason string

	// Module is the Go module path that might be affected.
	Module string

	// Package is the Go package path that might be affected.
	Package string

	// CVE is a copy of the CVE, for the NeedsIssue triage state.
	CVE *cve4.CVE

	// ReferenceURLs is a list of the URLs in the CVE references,
	// for the FalsePositive triage state.
	ReferenceURLs []string

	// IssueReference is a reference to the GitHub issue that was filed.
	// E.g. golang/vulndb#12345.
	// Set only after a GitHub issue has been successfully created.
	IssueReference string

	// IssueCreatedAt is the time when the issue was created.
	// Set only after a GitHub issue has been successfully created.
	IssueCreatedAt time.Time

	// History holds previous states of a CVE4Record,
	// from most to least recent.
	History []*CVE4RecordSnapshot
}

func (r *CVE4Record) GetID() string   { return r.ID }
func (r *CVE4Record) GetUnit() string { return r.Module }
func (r *CVE4Record) GetDescription() string {
	if r.CVE == nil || len(r.CVE.Description.Data) == 0 {
		return ""
	}
	return r.CVE.Description.Data[0].Value
}
func (r *CVE4Record) GetSource() report.Source     { return r.CVE }
func (r *CVE4Record) GetIssueReference() string    { return r.IssueReference }
func (r *CVE4Record) GetIssueCreatedAt() time.Time { return r.IssueCreatedAt }
func (r *CVE4Record) GetTriageState() TriageState  { return r.TriageState }

// Validate returns an error if the CVE4Record is not valid.
func (r *CVE4Record) Validate() error {
	if r.ID == "" {
		return errors.New("need ID")
	}
	if r.Path == "" {
		return errors.New("need Path")
	}
	if r.BlobHash == "" {
		return errors.New("need BlobHash")
	}
	if r.CommitHash == "" {
		return errors.New("need CommitHash")
	}
	if r.CommitTime.IsZero() {
		return errors.New("need CommitTime")
	}
	return r.TriageState.Validate()
}

// TriageState is the state of our work on the CVE or GHSA.
// It is implemented as a string rather than an int so that stored values are
// immune to renumbering.
type TriageState string

const (
	// No action is needed on the CVE or GHSA (perhaps because it is rejected, reserved or invalid).
	TriageStateNoActionNeeded TriageState = "NoActionNeeded"
	// The CVE needs to have an issue created.
	TriageStateNeedsIssue TriageState = "NeedsIssue"
	// An issue has been created in the issue tracker.
	// The IssueReference and IssueCreatedAt fields have more information.
	TriageStateIssueCreated TriageState = "IssueCreated"
	// This vulnerability has already been handled under an alias (i.e., a CVE
	// or GHSA that refers to the same vulnerability).
	TriageStateAlias TriageState = "Alias"
	// The CVE state was changed after the CVE was created.
	TriageStateUpdatedSinceIssueCreation TriageState = "UpdatedSinceIssueCreation"
	// Although the triager might think this CVE is relevant to Go, it is not.
	TriageStateFalsePositive TriageState = "FalsePositive"
	// There is already an entry in the Go vuln DB that covers this CVE.
	TriageStateHasVuln TriageState = "HasVuln"
)

// Validate returns an error if the TriageState is not one of the above values.
func (s TriageState) Validate() error {
	switch s {
	case TriageStateNoActionNeeded, TriageStateNeedsIssue, TriageStateIssueCreated, TriageStateAlias, TriageStateUpdatedSinceIssueCreation, TriageStateFalsePositive, TriageStateHasVuln:
		return nil
	default:
		return fmt.Errorf("bad TriageState %q", s)
	}
}

// NewCVE4Record creates a CVE4Record from a CVE, its path and its blob hash.
func NewCVE4Record(cve *cve4.CVE, path, blobHash string, commit *object.Commit) *CVE4Record {
	return &CVE4Record{
		ID:         cve.ID,
		CVEState:   cve.State,
		Path:       path,
		BlobHash:   blobHash,
		CommitHash: commit.Hash.String(),
		CommitTime: commit.Committer.When.In(time.UTC),
	}
}

// CVE4RecordSnapshot holds a previous state of a CVE4Record.
// The fields mean the same as those of CVE4Record.
type CVE4RecordSnapshot struct {
	CommitHash        string
	CVEState          string
	TriageState       TriageState
	TriageStateReason string
}

func (r *CVE4Record) Snapshot() *CVE4RecordSnapshot {
	return &CVE4RecordSnapshot{
		CommitHash:        r.CommitHash,
		CVEState:          r.CVEState,
		TriageState:       r.TriageState,
		TriageStateReason: r.TriageStateReason,
	}
}

// A CommitUpdateRecord describes a single update operation, which reconciles
// a commit in the CVE list repo with the DB state.
type CommitUpdateRecord struct {
	// The ID of this record in the DB. Needed to modify the record.
	ID string
	// When the update started and completed. If EndedAt is zero,
	// the update is in progress (or it crashed).
	StartedAt, EndedAt time.Time
	// The repo commit hash that this update is working on.
	CommitHash string
	// The time the commit occurred.
	CommitTime time.Time
	// The total number of CVEs being processed in this update.
	NumTotal int
	// The number currently processed. When this equals NumTotal, the
	// update is done.
	NumProcessed int
	// The number of CVEs added to the DB.
	NumAdded int
	// The number of CVEs modified.
	NumModified int
	// The error that stopped the update.
	Error string
	// The last time this record was updated.
	UpdatedAt time.Time `firestore:",serverTimestamp"`
}

// A LegacyGHSARecord holds information about a GitHub security advisory.
type LegacyGHSARecord struct {
	// GHSA is the advisory.
	GHSA *ghsa.SecurityAdvisory
	// TriageState is the state of our triage processing on the CVE.
	TriageState TriageState
	// TriageStateReason is an explanation of TriageState.
	TriageStateReason string
	// IssueReference is a reference to the GitHub issue that was filed.
	// E.g. golang/vulndb#12345.
	// Set only after a GitHub issue has been successfully created.
	IssueReference string
	// IssueCreatedAt is the time when the issue was created.
	// Set only after a GitHub issue has been successfully created.
	IssueCreatedAt time.Time
}

func (r *LegacyGHSARecord) GetID() string                { return r.GHSA.ID }
func (r *LegacyGHSARecord) GetUnit() string              { return r.GHSA.Vulns[0].Package }
func (r *LegacyGHSARecord) GetDescription() string       { return r.GHSA.Description }
func (r *LegacyGHSARecord) GetSource() report.Source     { return r.GHSA }
func (r *LegacyGHSARecord) GetIssueReference() string    { return r.IssueReference }
func (r *LegacyGHSARecord) GetIssueCreatedAt() time.Time { return r.IssueCreatedAt }
func (r *LegacyGHSARecord) GetTriageState() TriageState  { return r.TriageState }
func (r *LegacyGHSARecord) Validate() error              { return nil }

// A Store is a storage system for the CVE database.
type Store interface {
	// CreateCommitUpdateRecord creates a new CommitUpdateRecord. It should be called at the start
	// of an update. On successful return, the CommitUpdateRecord's ID field will be
	// set to a new, unique ID.
	CreateCommitUpdateRecord(context.Context, *CommitUpdateRecord) error

	// SetCommitUpdateRecord modifies the CommitUpdateRecord. Use the same record passed to
	// CreateCommitUpdateRecord, because it will have the correct ID.
	SetCommitUpdateRecord(context.Context, *CommitUpdateRecord) error

	// ListCommitUpdateRecords returns some of the CommitUpdateRecords in the store, from most to
	// least recent.
	ListCommitUpdateRecords(ctx context.Context, limit int) ([]*CommitUpdateRecord, error)

	// GetRecord returns the Record with the given id. If not found, it returns (nil, nil).
	GetRecord(ctx context.Context, id string) (Record, error)

	// ListCVE4RecordsWithTriageState returns all CVE4Records with the given triage state,
	// ordered by ID.
	ListCVE4RecordsWithTriageState(ctx context.Context, ts TriageState) ([]*CVE4Record, error)

	// GetDirectoryHash returns the hash for the tree object corresponding to dir.
	// If dir isn't found, it succeeds with the empty string.
	GetDirectoryHash(ctx context.Context, dir string) (string, error)

	// SetDirectoryHash sets the hash for the given directory.
	SetDirectoryHash(ctx context.Context, dir, hash string) error

	// RunTransaction runs the function in a transaction.
	RunTransaction(context.Context, func(context.Context, Transaction) error) error
}

// Transaction supports store operations that run inside a transaction.
type Transaction interface {
	// CreateRecord creates a new record.
	// It is an error if one with the same ID already exists.
	CreateRecord(Record) error

	// SetRecord sets the record in the database.
	// It is an error if no such record exists.
	SetRecord(Record) error

	// GetRecord returns a single record by ID.
	// If not found, it returns (nil, nil).
	GetRecord(id string) (Record, error)

	// GetRecords retrieves records for all CVE IDs between startID and
	// endID, inclusive.
	GetCVE4Records(startID, endID string) ([]*CVE4Record, error)

	// GetLegacyGHSARecords returns all the GHSARecords in the database.
	GetLegacyGHSARecords() ([]*LegacyGHSARecord, error)
}
