package utils

import (
	"io"
	"net/http"
	"strings"

	log "github.com/Sirupsen/logrus"
)

// VersionInfo is used to model entities which has a version.
// It is basically a tupple with name and version.
type VersionInfo interface {
	Name() string
	Version() string
}

func validVersion(version VersionInfo) bool {
	const stopChars = " \t\r\n/"
	name := version.Name()
	vers := version.Version()
	if len(name) == 0 || strings.ContainsAny(name, stopChars) {
		return false
	}
	if len(vers) == 0 || strings.ContainsAny(vers, stopChars) {
		return false
	}
	return true
}

// Convert versions to a string and append the string to the string base.
//
// Each VersionInfo will be converted to a string in the format of
// "product/version", where the "product" is get from the Name() method, while
// version is get from the Version() method. Several pieces of verson information
// will be concatinated and separated by space.
func appendVersions(base string, versions ...VersionInfo) string {
	if len(versions) == 0 {
		return base
	}

	verstrs := make([]string, 0, 1+len(versions))
	if len(base) > 0 {
		verstrs = append(verstrs, base)
	}

	for _, v := range versions {
		if !validVersion(v) {
			continue
		}
		verstrs = append(verstrs, v.Name()+"/"+v.Version())
	}
	return strings.Join(verstrs, " ")
}

// HTTPRequestDecorator is used to change an instance of
// http.Request. It could be used to add more header fields,
// change body, etc.
type HTTPRequestDecorator interface {
	// ChangeRequest() changes the request accordingly.
	// The changed request will be returned or err will be non-nil
	// if an error occur.
	ChangeRequest(req *http.Request) (newReq *http.Request, err error)
}

// HTTPUserAgentDecorator appends the product/version to the user agent field
// of a request.
type HTTPUserAgentDecorator struct {
	versions []VersionInfo
}

func NewHTTPUserAgentDecorator(versions ...VersionInfo) HTTPRequestDecorator {
	return &HTTPUserAgentDecorator{
		versions: versions,
	}
}

func (h *HTTPUserAgentDecorator) ChangeRequest(req *http.Request) (newReq *http.Request, err error) {
	if req == nil {
		return req, nil
	}

	userAgent := appendVersions(req.UserAgent(), h.versions...)
	if len(userAgent) > 0 {
		req.Header.Set("User-Agent", userAgent)
	}
	return req, nil
}

type HTTPMetaHeadersDecorator struct {
	Headers map[string][]string
}

func (h *HTTPMetaHeadersDecorator) ChangeRequest(req *http.Request) (newReq *http.Request, err error) {
	if h.Headers == nil {
		return req, nil
	}
	for k, v := range h.Headers {
		req.Header[k] = v
	}
	return req, nil
}

type HTTPAuthDecorator struct {
	login    string
	password string
}

func NewHTTPAuthDecorator(login, password string) HTTPRequestDecorator {
	return &HTTPAuthDecorator{
		login:    login,
		password: password,
	}
}

func (self *HTTPAuthDecorator) ChangeRequest(req *http.Request) (*http.Request, error) {
	req.SetBasicAuth(self.login, self.password)
	return req, nil
}

// HTTPRequestFactory creates an HTTP request
// and applies a list of decorators on the request.
type HTTPRequestFactory struct {
	decorators []HTTPRequestDecorator
}

func NewHTTPRequestFactory(d ...HTTPRequestDecorator) *HTTPRequestFactory {
	return &HTTPRequestFactory{
		decorators: d,
	}
}

func (self *HTTPRequestFactory) AddDecorator(d ...HTTPRequestDecorator) {
	self.decorators = append(self.decorators, d...)
}

func (self *HTTPRequestFactory) GetDecorators() []HTTPRequestDecorator {
	return self.decorators
}

// NewRequest() creates a new *http.Request,
// applies all decorators in the HTTPRequestFactory on the request,
// then applies decorators provided by d on the request.
func (h *HTTPRequestFactory) NewRequest(method, urlStr string, body io.Reader, d ...HTTPRequestDecorator) (*http.Request, error) {
	req, err := http.NewRequest(method, urlStr, body)
	if err != nil {
		return nil, err
	}

	// By default, a nil factory should work.
	if h == nil {
		return req, nil
	}
	for _, dec := range h.decorators {
		req, err = dec.ChangeRequest(req)
		if err != nil {
			return nil, err
		}
	}
	for _, dec := range d {
		req, err = dec.ChangeRequest(req)
		if err != nil {
			return nil, err
		}
	}
	log.Debugf("%v -- HEADERS: %v", req.URL, req.Header)
	return req, err
}
