package remotecontext // import "github.com/docker/docker/builder/remotecontext"

import (
	"bytes"
	"fmt"
	"io"
	"io/ioutil"
	"net"
	"net/http"
	"net/url"
	"regexp"

	"github.com/docker/docker/errdefs"
	"github.com/docker/docker/pkg/ioutils"
	"github.com/pkg/errors"
)

// When downloading remote contexts, limit the amount (in bytes)
// to be read from the response body in order to detect its Content-Type
const maxPreambleLength = 100

const acceptableRemoteMIME = `(?:application/(?:(?:x\-)?tar|octet\-stream|((?:x\-)?(?:gzip|bzip2?|xz)))|(?:text/plain))`

var mimeRe = regexp.MustCompile(acceptableRemoteMIME)

// downloadRemote context from a url and returns it, along with the parsed content type
func downloadRemote(remoteURL string) (string, io.ReadCloser, error) {
	response, err := GetWithStatusError(remoteURL)
	if err != nil {
		return "", nil, errors.Wrapf(err, "error downloading remote context %s", remoteURL)
	}

	contentType, contextReader, err := inspectResponse(
		response.Header.Get("Content-Type"),
		response.Body,
		response.ContentLength)
	if err != nil {
		response.Body.Close()
		return "", nil, errors.Wrapf(err, "error detecting content type for remote %s", remoteURL)
	}

	return contentType, ioutils.NewReadCloserWrapper(contextReader, response.Body.Close), nil
}

// GetWithStatusError does an http.Get() and returns an error if the
// status code is 4xx or 5xx.
func GetWithStatusError(address string) (resp *http.Response, err error) {
	if resp, err = http.Get(address); err != nil {
		if uerr, ok := err.(*url.Error); ok {
			if derr, ok := uerr.Err.(*net.DNSError); ok && !derr.IsTimeout {
				return nil, errdefs.NotFound(err)
			}
		}
		return nil, errdefs.System(err)
	}
	if resp.StatusCode < 400 {
		return resp, nil
	}
	msg := fmt.Sprintf("failed to GET %s with status %s", address, resp.Status)
	body, err := ioutil.ReadAll(resp.Body)
	resp.Body.Close()
	if err != nil {
		return nil, errdefs.System(errors.New(msg + ": error reading body"))
	}

	msg += ": " + string(bytes.TrimSpace(body))
	switch resp.StatusCode {
	case http.StatusNotFound:
		return nil, errdefs.NotFound(errors.New(msg))
	case http.StatusBadRequest:
		return nil, errdefs.InvalidParameter(errors.New(msg))
	case http.StatusUnauthorized:
		return nil, errdefs.Unauthorized(errors.New(msg))
	case http.StatusForbidden:
		return nil, errdefs.Forbidden(errors.New(msg))
	}
	return nil, errdefs.Unknown(errors.New(msg))
}

// inspectResponse looks into the http response data at r to determine whether its
// content-type is on the list of acceptable content types for remote build contexts.
// This function returns:
//    - a string representation of the detected content-type
//    - an io.Reader for the response body
//    - an error value which will be non-nil either when something goes wrong while
//      reading bytes from r or when the detected content-type is not acceptable.
func inspectResponse(ct string, r io.Reader, clen int64) (string, io.Reader, error) {
	plen := clen
	if plen <= 0 || plen > maxPreambleLength {
		plen = maxPreambleLength
	}

	preamble := make([]byte, plen)
	rlen, err := r.Read(preamble)
	if rlen == 0 {
		return ct, r, errors.New("empty response")
	}
	if err != nil && err != io.EOF {
		return ct, r, err
	}

	preambleR := bytes.NewReader(preamble[:rlen])
	bodyReader := io.MultiReader(preambleR, r)
	// Some web servers will use application/octet-stream as the default
	// content type for files without an extension (e.g. 'Dockerfile')
	// so if we receive this value we better check for text content
	contentType := ct
	if len(ct) == 0 || ct == mimeTypes.OctetStream {
		contentType, _, err = detectContentType(preamble)
		if err != nil {
			return contentType, bodyReader, err
		}
	}

	contentType = selectAcceptableMIME(contentType)
	var cterr error
	if len(contentType) == 0 {
		cterr = fmt.Errorf("unsupported Content-Type %q", ct)
		contentType = ct
	}

	return contentType, bodyReader, cterr
}

func selectAcceptableMIME(ct string) string {
	return mimeRe.FindString(ct)
}
