// 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.
package storage

import (
	"io"
	"net/http"
	"net/url"

	"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(q string) *Query {
	hc := c.httpClient()

	resp, err := hc.Get(c.BaseURL + "/search?" + url.Values{"q": []string{q}}.Encode())
	if err != nil {
		return &Query{err: err}
	}

	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 {
	q.body.Close()
	return q.err
}

// TODO(quentin): Move upload code here from cmd/benchsave?
