// Copyright 2013 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 or at
// https://developers.google.com/open-source/licenses/bsd.

package gosrc

import (
	"context"
	"encoding/json"
	"fmt"
	"io"
	"io/ioutil"
	"net/http"
)

type httpClient struct {
	errFn  func(*http.Response) error
	header http.Header
	client *http.Client
}

func (c *httpClient) err(resp *http.Response) error {
	if resp.StatusCode == 404 {
		return NotFoundError{Message: "Resource not found: " + resp.Request.URL.String()}
	}
	if c.errFn != nil {
		return c.errFn(resp)
	}
	return &RemoteError{resp.Request.URL.Host, fmt.Errorf("%d: (%s)", resp.StatusCode, resp.Request.URL.String())}
}

// get issues a GET to the specified URL.
func (c *httpClient) get(ctx context.Context, url string) (*http.Response, error) {
	req, err := http.NewRequest("GET", url, nil)
	if err != nil {
		return nil, err
	}

	// Take the trace ID to group all outbound requests together.
	req = req.WithContext(ctx)
	for k, vs := range c.header {
		req.Header[k] = vs
	}
	resp, err := c.client.Do(req)
	if err != nil {
		return nil, &RemoteError{req.URL.Host, err}
	}
	return resp, err
}

// getNoFollow issues a GET to the specified URL without following redirects.
func (c *httpClient) getNoFollow(url string) (*http.Response, error) {
	req, err := http.NewRequest("GET", url, nil)
	if err != nil {
		return nil, err
	}
	for k, vs := range c.header {
		req.Header[k] = vs
	}
	t := c.client.Transport
	if t == nil {
		t = http.DefaultTransport
	}
	resp, err := t.RoundTrip(req)
	if err != nil {
		return nil, &RemoteError{req.URL.Host, err}
	}
	return resp, err
}

func (c *httpClient) getBytes(ctx context.Context, url string) ([]byte, error) {
	resp, err := c.get(ctx, url)
	if err != nil {
		return nil, err
	}
	defer resp.Body.Close()
	if resp.StatusCode != 200 {
		return nil, c.err(resp)
	}
	p, err := ioutil.ReadAll(resp.Body)
	return p, err
}

func (c *httpClient) getReader(ctx context.Context, url string) (io.ReadCloser, error) {
	resp, err := c.get(ctx, url)
	if err != nil {
		return nil, err
	}
	if resp.StatusCode != 200 {
		err = c.err(resp)
		resp.Body.Close()
		return nil, err
	}
	return resp.Body, nil
}

func (c *httpClient) getJSON(ctx context.Context, url string, v interface{}) (*http.Response, error) {
	resp, err := c.get(ctx, url)
	if err != nil {
		return resp, err
	}
	defer resp.Body.Close()
	if resp.StatusCode != 200 {
		return resp, c.err(resp)
	}
	err = json.NewDecoder(resp.Body).Decode(v)
	if _, ok := err.(*json.SyntaxError); ok {
		err = NotFoundError{Message: "JSON syntax error at " + url}
	}
	return resp, err
}

func (c *httpClient) getFiles(ctx context.Context, urls []string, files []*File) error {
	ch := make(chan error, len(files))
	for i := range files {
		go func(i int) {
			resp, err := c.get(ctx, urls[i])
			if err != nil {
				ch <- err
				return
			}
			defer resp.Body.Close()
			if resp.StatusCode != 200 {
				var err error
				if c.errFn != nil {
					err = c.errFn(resp)
				} else {
					err = &RemoteError{resp.Request.URL.Host, fmt.Errorf("get %s -> %d", urls[i], resp.StatusCode)}
				}
				ch <- err
				return
			}
			files[i].Data, err = ioutil.ReadAll(resp.Body)
			if err != nil {
				ch <- &RemoteError{resp.Request.URL.Host, err}
				return
			}
			ch <- nil
		}(i)
	}
	for range files {
		if err := <-ch; err != nil {
			return err
		}
	}
	return nil
}
