// Copyright 2017 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 storage contains a client for the performance data storage server.
//
// Deprecated: Moved to golang.org/x/build/perfdata.
package storage

import (
	"context"
	"encoding/json"
	"fmt"
	"io"
	"mime/multipart"
	"net/http"
	"net/url"

	"golang.org/x/net/context/ctxhttp"
	"golang.org/x/perf/storage/benchfmt"
)

// A Client issues queries to a performance data storage server.
// It is safe to use from multiple goroutines simultaneously.
type Client struct {
	// BaseURL is the base URL of the storage server.
	BaseURL string
	// HTTPClient is the HTTP client for sending requests. If nil, http.DefaultClient will be used.
	HTTPClient *http.Client
}

// httpClient returns the http.Client to use for requests.
func (c *Client) httpClient() *http.Client {
	if c.HTTPClient != nil {
		return c.HTTPClient
	}
	return http.DefaultClient
}

// Query searches for results matching the given query string.
//
// The query string is first parsed into quoted words (as in the shell)
// and then each word must be formatted as one of the following:
// key:value - exact match on label "key" = "value"
// key>value - value greater than (useful for dates)
// key<value - value less than (also useful for dates)
func (c *Client) Query(ctx context.Context, q string) *Query {
	hc := c.httpClient()

	resp, err := ctxhttp.Get(ctx, hc, c.BaseURL+"/search?"+url.Values{"q": []string{q}}.Encode())
	if err != nil {
		return &Query{err: err}
	}
	if resp.StatusCode != 200 {
		defer resp.Body.Close()
		body, err := io.ReadAll(resp.Body)
		if err != nil {
			return &Query{err: err}
		}
		return &Query{err: fmt.Errorf("%s", body)}
	}

	br := benchfmt.NewReader(resp.Body)

	return &Query{br: br, body: resp.Body}
}

// A Query allows iteration over the results of a search query.
// Use Next to advance through the results, making sure to call Close when done:
//
//	q := client.Query("key:value")
//	defer q.Close()
//	for q.Next() {
//	  res := q.Result()
//	  ...
//	}
//	if err = q.Err(); err != nil {
//	  // handle error encountered during query
//	}
type Query struct {
	br   *benchfmt.Reader
	body io.ReadCloser
	err  error
}

// Next prepares the next result for reading with the Result
// method. It returns false when there are no more results, either by
// reaching the end of the input or an error.
func (q *Query) Next() bool {
	if q.err != nil {
		return false
	}
	return q.br.Next()
}

// Result returns the most recent result generated by a call to Next.
func (q *Query) Result() *benchfmt.Result {
	return q.br.Result()
}

// Err returns the first error encountered during the query.
func (q *Query) Err() error {
	if q.err != nil {
		return q.err
	}
	return q.br.Err()
}

// Close frees resources associated with the query.
func (q *Query) Close() error {
	if q.body != nil {
		q.body.Close()
		q.body = nil
	}
	return q.err
}

// UploadInfo represents an upload summary.
type UploadInfo struct {
	Count       int
	UploadID    string
	LabelValues benchfmt.Labels `json:",omitempty"`
}

// ListUploads searches for uploads containing results matching the given query string.
// The query may be empty, in which case all uploads will be returned.
// extraLabels specifies other labels to be retrieved.
// If limit is 0, no limit will be provided to the server.
// The uploads are returned starting with the most recent upload.
func (c *Client) ListUploads(ctx context.Context, q string, extraLabels []string, limit int) *UploadList {
	hc := c.httpClient()

	v := url.Values{"extra_label": extraLabels}
	if q != "" {
		v["q"] = []string{q}
	}
	if limit != 0 {
		v["limit"] = []string{fmt.Sprintf("%d", limit)}
	}

	u := c.BaseURL + "/uploads"
	if len(v) > 0 {
		u += "?" + v.Encode()
	}
	resp, err := ctxhttp.Get(ctx, hc, u)
	if err != nil {
		return &UploadList{err: err}
	}
	if resp.StatusCode != 200 {
		body, err := io.ReadAll(resp.Body)
		if err != nil {
			return &UploadList{err: err}
		}
		return &UploadList{err: fmt.Errorf("%s", body)}
	}
	return &UploadList{body: resp.Body, dec: json.NewDecoder(resp.Body)}
}

// UploadList is the result of ListUploads.
// Use Next to advance through the rows, making sure to call Close when done:
//
//	q := db.ListUploads("key:value")
//	defer q.Close()
//	for q.Next() {
//	  id, count := q.Row()
//	  labels := q.LabelValues()
//	  ...
//	}
//	err = q.Err() // get any error encountered during iteration
//	...
type UploadList struct {
	body io.Closer
	dec  *json.Decoder
	// from last call to Next
	ui  UploadInfo
	err error
}

// Next prepares the next result for reading with the Result
// method. It returns false when there are no more results, either by
// reaching the end of the input or an error.
func (ul *UploadList) Next() bool {
	if ul.err != nil {
		return false
	}

	// Clear UploadInfo before decoding new value.
	ul.ui = UploadInfo{}

	ul.err = ul.dec.Decode(&ul.ui)
	return ul.err == nil
}

// Info returns the most recent UploadInfo generated by a call to Next.
func (ul *UploadList) Info() UploadInfo {
	return ul.ui
}

// Err returns the error state of the query.
func (ul *UploadList) Err() error {
	if ul.err == io.EOF {
		return nil
	}
	return ul.err
}

// Close frees resources associated with the query.
func (ul *UploadList) Close() error {
	if ul.body != nil {
		err := ul.body.Close()
		ul.body = nil
		return err
	}
	return ul.Err()
}

// NewUpload starts a new upload to the storage server.
// The upload must have Abort or Commit called on it.
// If the server requires authentication for uploads, c.HTTPClient should be set to the result of oauth2.NewClient.
func (c *Client) NewUpload(ctx context.Context) *Upload {
	hc := c.httpClient()

	pr, pw := io.Pipe()
	mpw := multipart.NewWriter(pw)

	req, err := http.NewRequest("POST", c.BaseURL+"/upload", pr)
	if err != nil {
		return &Upload{err: err}
	}
	req.Header.Set("Content-Type", mpw.FormDataContentType())
	req.Header.Set("User-Agent", "golang.org/x/perf/storage")
	errCh := make(chan error)
	u := &Upload{pw: pw, mpw: mpw, errCh: errCh}
	go func() {
		resp, err := ctxhttp.Do(ctx, hc, req)
		if err != nil {
			errCh <- err
			return
		}
		defer resp.Body.Close()
		if resp.StatusCode != 200 {
			body, _ := io.ReadAll(resp.Body)
			errCh <- fmt.Errorf("upload failed: %v\n%s", resp.Status, body)
			return
		}
		status := &UploadStatus{}
		if err := json.NewDecoder(resp.Body).Decode(status); err != nil {
			errCh <- err
		}
		u.status = status
		errCh <- nil
	}()
	return u
}

// UploadStatus contains information about a successful upload.
type UploadStatus struct {
	// UploadID is the upload ID assigned to the upload.
	UploadID string `json:"uploadid"`
	// FileIDs is the list of file IDs assigned to the files in the upload.
	FileIDs []string `json:"fileids"`
	// ViewURL is a server-supplied URL to view the results.
	ViewURL string `json:"viewurl"`
}

// An Upload is an in-progress upload.
// Use CreateFile to upload one or more files, then call Commit or Abort.
//
//	u := client.NewUpload()
//	w, err := u.CreateFile()
//	if err != nil {
//	  u.Abort()
//	  return err
//	}
//	fmt.Fprintf(w, "BenchmarkResult 1 1 ns/op\n")
//	if err := u.Commit(); err != nil {
//	  return err
//	}
type Upload struct {
	pw     io.WriteCloser
	mpw    *multipart.Writer
	status *UploadStatus
	// errCh is used to report the success/failure of the HTTP request
	errCh chan error
	// err is the first observed error; it is only accessed from user-called methods for thread safety
	err error
}

// CreateFile creates a new upload with the given name.
// The Writer may be used until CreateFile is called again.
// name may be the empty string if the file does not have a name.
func (u *Upload) CreateFile(name string) (io.Writer, error) {
	if u.err != nil {
		return nil, u.err
	}
	return u.mpw.CreateFormFile("file", name)
}

// Commit attempts to commit the upload.
func (u *Upload) Commit() (*UploadStatus, error) {
	if u.err != nil {
		return nil, u.err
	}
	if u.err = u.mpw.WriteField("commit", "1"); u.err != nil {
		u.Abort()
		return nil, u.err
	}
	if u.err = u.mpw.Close(); u.err != nil {
		u.Abort()
		return nil, u.err
	}
	u.mpw = nil
	if u.err = u.pw.Close(); u.err != nil {
		u.Abort()
		return nil, u.err
	}
	u.pw = nil
	u.err = <-u.errCh
	u.errCh = nil
	if u.err != nil {
		return nil, u.err
	}
	return u.status, nil
}

// Abort attempts to cancel the in-progress upload.
func (u *Upload) Abort() error {
	if u.mpw != nil {
		u.mpw.WriteField("abort", "1")
		// Writing the 'abort' field will cause the server to send back an error response.
		u.mpw.Close()
		u.mpw = nil
	}
	if u.pw != nil {
		u.pw.Close()
		u.pw = nil
	}
	err := <-u.errCh
	u.errCh = nil
	if u.err == nil {
		u.err = err
	}
	return u.err
}
