// Copyright 2022 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 cveclient implements a client for interacting with MITRE CVE
// Services API as described at https://cveawg.mitre.org/api-docs/openapi.json.
package cveclient

import (
	"bytes"
	"encoding/json"
	"fmt"
	"io"
	"net/http"
	"net/url"
	"strconv"
	"strings"
	"time"

	"golang.org/x/vulndb/internal/cveschema5"
)

const (
	// ProdEndpoint is the production endpoint
	ProdEndpoint = "https://cveawg.mitre.org"
	// TestEndpoint is the test endpoint
	TestEndpoint = "https://cveawg-test.mitre.org"
	// DevEndpoint is the dev endpoint
	DevEndpoint = "https://cveawg-dev.mitre.org"

	// WebURL is the URL to view production CVE records on the web.
	WebURL = "https://www.cve.org"
	// TestWebURL is the URL to view test CVE records on the web.
	TestWebURL = "https://test.cve.org"
)

// Client is a MITRE CVE Services API client.
type Client struct {
	Config
	c *http.Client
}

// WebURL returns the URL that can be used to view a published
// CVE record on the web.
func (c *Client) WebURL(cveID string) string {
	baseURL := WebURL
	if c.Config.Endpoint == TestEndpoint {
		baseURL = TestWebURL
	}
	return fmt.Sprintf("%s/CVERecord?id=%s", baseURL, cveID)
}

// Config contains client configuration data.
type Config struct {
	// Endpoint is the endpoint to access when making API calls. Required.
	Endpoint string
	// Org is the shortname for the organization that is authenticated when
	// making API calls. Required.
	Org string
	// Key is the user's API key. Required.
	Key string
	// User is the username for the account that is making API calls. Required.
	User string
}

// New returns an initialized client configured via cfg.
func New(cfg Config) *Client {
	return &Client{cfg, http.DefaultClient}
}

// AssignedCVE contains information about an assigned CVE.
type AssignedCVE struct {
	ID          string           `json:"cve_id"`
	Year        string           `json:"cve_year"`
	State       cveschema5.State `json:"state"`
	CNA         string           `json:"owning_cna"`
	Reserved    time.Time        `json:"reserved"`
	RequestedBy RequestedBy      `json:"requested_by"`
}

// RequestedBy indicates the requesting user and organization for a CVE.
type RequestedBy struct {
	CNA  string `json:"cna"`
	User string `json:"user"`
}

func (c AssignedCVE) String() string {
	return fmt.Sprintf("%s: state=%s, cna=%s, requester=%s", c.ID, c.State, c.CNA, c.RequestedBy.User)
}

// AssignedCVEList is a list of AssignedCVEs.
type AssignedCVEList []AssignedCVE

// ShortString outputs a formatted string of newline-separated CVE IDs.
func (cs AssignedCVEList) ShortString() string {
	strs := []string{}
	for _, c := range cs {
		strs = append(strs, c.ID)
	}
	return strings.Join(strs, "\n")
}

// String outputs a formatted string of newline-separated CVE data.
func (cs AssignedCVEList) String() string {
	strs := []string{}
	for _, c := range cs {
		strs = append(strs, c.String())
	}
	return strings.Join(strs, "\n")
}

// ReserveOptions contains the configuration options for reserving new
// CVE IDs.
type ReserveOptions struct {
	// NumIDs is the the number of CVE IDs to reserve. Required.
	NumIDs int
	// Year is the CVE ID year for new IDs, indicating the year the
	// vulnerability was discovered. Required.
	Year int
	// Mode indicates whether the block of CVEs should be in sequence.
	// Relevant only if NumIDs > 1.
	Mode RequestType
}

// RequestType is the type of CVE ID reserve request.
type RequestType string

const (
	// SequentialRequest requests CVE IDs be reserved in a sequential fashion.
	SequentialRequest RequestType = "sequential"
	// NonsequentialRequest requests CVE IDs be reserved in a nonsequential fashion.
	NonsequentialRequest RequestType = "nonsequential"
)

func (o *ReserveOptions) urlParams(org string) url.Values {
	params := url.Values{}
	params.Set("amount", fmt.Sprint(o.NumIDs))
	if o.Year != 0 {
		params.Set("cve_year", strconv.Itoa(o.Year))
	}
	params.Set("short_name", org)
	if o.NumIDs > 1 {
		params.Set("batch_type", string(o.Mode))
	}
	return params
}

func (c *Client) createReserveIDsRequest(opts ReserveOptions) (*http.Request, error) {
	req, err := c.createRequest(http.MethodPost,
		c.requestURL(cveIDTarget), nil)
	if err != nil {
		return nil, err
	}
	req.URL.RawQuery = opts.urlParams(c.Org).Encode()
	return req, err
}

type reserveIDsResponse struct {
	CVEs AssignedCVEList `json:"cve_ids"`
}

// ReserveIDs sends a request to the CVE API to reserve a block of CVE IDs.
// Returns a list of the reserved CVE IDs and their associated data.
// There may be fewer IDs than requested if, for example, the organization's
// quota is reached.
func (c *Client) ReserveIDs(opts ReserveOptions) (AssignedCVEList, error) {
	req, err := c.createReserveIDsRequest(opts)
	if err != nil {
		return nil, err
	}
	var assigned reserveIDsResponse
	checkStatus := func(s int) bool {
		return s == http.StatusOK || s == http.StatusPartialContent
	}
	err = c.sendRequest(req, checkStatus, &assigned)
	if err != nil {
		return nil, err
	}
	return assigned.CVEs, nil
}

// Quota contains information about an organizations reservation quota.
type Quota struct {
	Quota     int `json:"id_quota"`
	Reserved  int `json:"total_reserved"`
	Available int `json:"available"`
}

// RetrieveQuota queries the API for the organizations reservation quota.
func (c *Client) RetrieveQuota() (q *Quota, err error) {
	err = c.queryAPI(http.MethodGet, c.requestURL(orgTarget, c.Org, quotaTarget), nil, &q)
	return
}

// RetrieveID requests information about an assigned CVE ID.
func (c *Client) RetrieveID(id string) (cve *AssignedCVE, err error) {
	err = c.queryAPI(http.MethodGet, c.requestURL(cveIDTarget, id), nil, &cve)
	return
}

// RetrieveRecord requests a CVE record.
func (c *Client) RetrieveRecord(id string) (cve *cveschema5.CVERecord, err error) {
	err = c.queryAPI(http.MethodGet, c.requestURL(cveTarget, id), nil, &cve)
	return
}

func (c *Client) cveRecordEndpoint(cveID string) string {
	return c.requestURL(cveTarget, cveID, cnaTarget)
}

type recordRequestBody struct {
	CNAContainer cveschema5.CNAPublishedContainer `json:"cnaContainer"`
}
type createResponse struct {
	Created cveschema5.CVERecord `json:"created"`
}

func (c *Client) CreateRecord(id string, record *cveschema5.Containers) (*cveschema5.CVERecord, error) {
	requestBody := recordRequestBody{
		CNAContainer: record.CNAContainer,
	}
	var response createResponse
	err := c.queryAPI(http.MethodPost, c.cveRecordEndpoint(id), requestBody, &response)
	if err != nil {
		return nil, err
	}
	return &response.Created, nil
}

type updateResponse struct {
	Updated cveschema5.CVERecord `json:"updated"`
}

func (c *Client) UpdateRecord(id string, record *cveschema5.Containers) (*cveschema5.CVERecord, error) {
	requestBody := recordRequestBody{
		CNAContainer: record.CNAContainer,
	}
	var response updateResponse
	err := c.queryAPI(http.MethodPut, c.cveRecordEndpoint(id), requestBody, &response)
	if err != nil {
		return nil, err
	}
	return &response.Updated, nil
}

type Org struct {
	Name      string `json:"name"`
	ShortName string `json:"short_name"`
	UUID      string `json:"UUID"`
}

// RetrieveOrg requests information about an organization.
func (c *Client) RetrieveOrg() (org *Org, err error) {
	err = c.queryAPI(http.MethodGet, c.requestURL(orgTarget, c.Org), nil, &org)
	return
}

// ListOptions contains filters to be used when requesting a list of
// assigned CVEs.
type ListOptions struct {
	State          string
	Year           int
	ReservedBefore *time.Time
	ReservedAfter  *time.Time
	ModifiedBefore *time.Time
	ModifiedAfter  *time.Time
}

func (o ListOptions) String() string {
	var s []string
	if o.State != "" {
		s = append(s, fmt.Sprintf("state=%s", o.State))
	}
	if o.Year != 0 {
		s = append(s, fmt.Sprintf("year=%d", o.Year))
	}
	if o.ReservedBefore != nil {
		s = append(s, fmt.Sprintf("reserved_before=%s", o.ReservedBefore.Format(time.RFC3339)))
	}
	if o.ReservedAfter != nil {
		s = append(s, fmt.Sprintf("reserved_after=%s", o.ReservedAfter.Format(time.RFC3339)))
	}
	if o.ModifiedBefore != nil {
		s = append(s, fmt.Sprintf("modified_before=%s", o.ModifiedBefore.Format(time.RFC3339)))
	}
	if o.ModifiedAfter != nil {
		s = append(s, fmt.Sprintf("modified_after=%s", o.ModifiedAfter.Format(time.RFC3339)))
	}
	return strings.Join(s, ", ")
}

func (o *ListOptions) urlParams() url.Values {
	params := url.Values{}
	if o == nil {
		return params
	}
	if o.State != "" {
		params.Set("state", o.State)
	}
	if o.Year != 0 {
		params.Set("cve_id_year", strconv.Itoa(o.Year))
	}
	if o.ReservedBefore != nil {
		params.Set("time_reserved.lt", o.ReservedBefore.Format(time.RFC3339))
	}
	if o.ReservedAfter != nil {
		params.Set("time_reserved.gt", o.ReservedAfter.Format(time.RFC3339))
	}
	if o.ModifiedBefore != nil {
		params.Set("time_modified.lt", o.ModifiedBefore.Format(time.RFC3339))
	}
	if o.ModifiedAfter != nil {
		params.Set("time_modified.gt", o.ModifiedAfter.Format(time.RFC3339))
	}
	return params
}

type listOrgCVEsResponse struct {
	CurrentPage int             `json:"currentPage"`
	NextPage    int             `json:"nextPage"`
	CVEs        AssignedCVEList `json:"cve_ids"`
}

func (c Client) createListOrgCVEsRequest(opts *ListOptions, page int) (req *http.Request, err error) {
	req, err = c.createRequest(http.MethodGet, c.requestURL(cveIDTarget), nil)
	if err != nil {
		return nil, err
	}
	params := opts.urlParams()
	if page > 0 {
		params.Set("page", fmt.Sprint(page))
	}
	req.URL.RawQuery = params.Encode()
	return
}

// ListOrgCVEs requests information about the CVEs the organization has been
// assigned. This list can be filtered by setting the fields in opts.
func (c *Client) ListOrgCVEs(opts *ListOptions) (AssignedCVEList, error) {
	var cves []AssignedCVE
	page := 0
	for {
		req, err := c.createListOrgCVEsRequest(opts, page)
		if err != nil {
			return nil, err
		}
		var result listOrgCVEsResponse
		err = c.sendRequest(req, nil, &result)
		if err != nil {
			return nil, err
		}
		cves = append(cves, result.CVEs...)
		if result.NextPage <= result.CurrentPage {
			break
		}
		page = result.NextPage
	}
	return cves, nil
}

func (c *Client) queryAPI(method, url string, requestBody any, response any) error {
	req, err := c.createRequest(method, url, requestBody)
	if err != nil {
		return err
	}
	err = c.sendRequest(req, nil, response)
	if err != nil {
		return err
	}
	return nil
}

var (
	headerApiUser = "CVE-API-USER"
	headerApiOrg  = "CVE-API-ORG"
	headerApiKey  = "CVE-API-KEY"
)

// createRequest creates a new HTTP request and sets the header fields.
func (c *Client) createRequest(method, url string, body any) (*http.Request, error) {
	var r io.Reader
	if body != nil {
		b, err := json.Marshal(body)
		if err != nil {
			return nil, err
		}
		r = bytes.NewReader(b)
	}
	req, err := http.NewRequest(method, url, r)
	if err != nil {
		return nil, err
	}
	req.Header.Set(headerApiUser, c.User)
	req.Header.Set(headerApiOrg, c.Org)
	req.Header.Set(headerApiKey, c.Key)
	req.Header.Set("Content-Type", "application/json")
	return req, nil
}

// sendRequest sends an HTTP request, checks the returned status via
// checkStatus, and attempts to unmarshal the response into result.
// if checkStatus is nil, checks for http.StatusOK.
func (c *Client) sendRequest(req *http.Request, checkStatus func(int) bool, result any) (err error) {
	resp, err := c.c.Do(req)
	if err != nil {
		return fmt.Errorf("could not send HTTP request: %v", err)
	}
	defer resp.Body.Close()
	if checkStatus == nil {
		checkStatus = func(s int) bool {
			return s == http.StatusOK
		}
	}
	if !checkStatus(resp.StatusCode) {
		return fmt.Errorf("HTTP request %s %q returned error: %v", req.Method, req.URL, extractError(resp))
	}
	body, err := io.ReadAll(resp.Body)
	if err != nil {
		return err
	}
	if err := json.Unmarshal(body, result); err != nil {
		return err
	}
	return nil
}

var (
	cveTarget   = "cve"
	cveIDTarget = "cve-id"
	orgTarget   = "org"
	quotaTarget = "id_quota"
	cnaTarget   = "cna"
)

func (c *Client) requestURL(targets ...string) string {
	return fmt.Sprintf("%s/api/%s", c.Endpoint, strings.Join(targets, "/"))
}

type apiError struct {
	Error   string         `json:"error"`
	Message string         `json:"message"`
	Detail  apiErrorDetail `json:"details"`
}

type apiErrorDetail struct {
	Errors []apiErrorInner `json:"errors"`
}

type apiErrorInner struct {
	InstancePath string `json:"instancePath"`
	Message      string `json:"message"`
}

// extractError extracts additional error messages from the HTTP response
// if available, and wraps them into a single error.
func extractError(resp *http.Response) error {
	errMsg := resp.Status
	body, err := io.ReadAll(resp.Body)
	if err != nil {
		return fmt.Errorf("%s: could not read error data: %s", errMsg, err)
	}
	var apiErr apiError
	if err := json.Unmarshal(body, &apiErr); err != nil {
		return fmt.Errorf("%s: could not unmarshal error: %s", errMsg, err)
	}

	// Append the error and message text if they add extra information
	// beyond the HTTP status text.
	statusText := strings.ToLower(http.StatusText(resp.StatusCode))
	for _, errText := range []string{apiErr.Error, apiErr.Message} {
		if errText != "" && strings.ToLower(errText) != statusText {
			errMsg = fmt.Sprintf("%s: %s", errMsg, errText)
		}
	}

	for _, detail := range apiErr.Detail.Errors {
		errMsg = fmt.Sprintf("%s\n  %s: %s", errMsg, detail.InstancePath, detail.Message)
	}

	return fmt.Errorf(errMsg)
}
