// Copyright 2009 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.

// HTTP Response reading and parsing.

package http

import (
	"bufio"
	"io"
	"os"
	"strconv"
	"strings"
)

// Response represents the response from an HTTP request.
//
type Response struct {
	Status     string // e.g. "200 OK"
	StatusCode int    // e.g. 200
	Proto      string // e.g. "HTTP/1.0"
	ProtoMajor int    // e.g. 1
	ProtoMinor int    // e.g. 0

	// RequestMethod records the method used in the HTTP request.
	// Header fields such as Content-Length have method-specific meaning.
	RequestMethod string // e.g. "HEAD", "CONNECT", "GET", etc.

	// Header maps header keys to values.  If the response had multiple
	// headers with the same key, they will be concatenated, with comma
	// delimiters.  (Section 4.2 of RFC 2616 requires that multiple headers
	// be semantically equivalent to a comma-delimited sequence.) Values
	// duplicated by other fields in this struct (e.g., ContentLength) are
	// omitted from Header.
	//
	// Keys in the map are canonicalized (see CanonicalHeaderKey).
	Header map[string]string

	// Body represents the response body.
	Body io.ReadCloser

	// ContentLength records the length of the associated content.  The
	// value -1 indicates that the length is unknown.  Unless RequestMethod
	// is "HEAD", values >= 0 indicate that the given number of bytes may
	// be read from Body.
	ContentLength int64

	// Contains transfer encodings from outer-most to inner-most. Value is
	// nil, means that "identity" encoding is used.
	TransferEncoding []string

	// Close records whether the header directed that the connection be
	// closed after reading Body.  The value is advice for clients: neither
	// ReadResponse nor Response.Write ever closes a connection.
	Close bool

	// Trailer maps trailer keys to values.  Like for Header, if the
	// response has multiple trailer lines with the same key, they will be
	// concatenated, delimited by commas.
	Trailer map[string]string
}

// ReadResponse reads and returns an HTTP response from r.  The RequestMethod
// parameter specifies the method used in the corresponding request (e.g.,
// "GET", "HEAD").  Clients must call resp.Body.Close when finished reading
// resp.Body.  After that call, clients can inspect resp.Trailer to find
// key/value pairs included in the response trailer.
func ReadResponse(r *bufio.Reader, requestMethod string) (resp *Response, err os.Error) {

	resp = new(Response)

	resp.RequestMethod = strings.ToUpper(requestMethod)

	// Parse the first line of the response.
	line, err := readLine(r)
	if err != nil {
		return nil, err
	}
	f := strings.Split(line, " ", 3)
	if len(f) < 3 {
		return nil, &badStringError{"malformed HTTP response", line}
	}
	resp.Status = f[1] + " " + f[2]
	resp.StatusCode, err = strconv.Atoi(f[1])
	if err != nil {
		return nil, &badStringError{"malformed HTTP status code", f[1]}
	}

	resp.Proto = f[0]
	var ok bool
	if resp.ProtoMajor, resp.ProtoMinor, ok = parseHTTPVersion(resp.Proto); !ok {
		return nil, &badStringError{"malformed HTTP version", resp.Proto}
	}

	// Parse the response headers.
	nheader := 0
	resp.Header = make(map[string]string)
	for {
		key, value, err := readKeyValue(r)
		if err != nil {
			return nil, err
		}
		if key == "" {
			break // end of response header
		}
		if nheader++; nheader >= maxHeaderLines {
			return nil, ErrHeaderTooLong
		}
		resp.AddHeader(key, value)
	}

	fixPragmaCacheControl(resp.Header)

	// Transfer encoding, content length
	resp.TransferEncoding, err = fixTransferEncoding(resp.Header)
	if err != nil {
		return nil, err
	}

	resp.ContentLength, err = fixLength(resp.StatusCode, resp.RequestMethod,
		resp.Header, resp.TransferEncoding)
	if err != nil {
		return nil, err
	}

	// Closing
	resp.Close = shouldClose(resp.ProtoMajor, resp.ProtoMinor, resp.Header)

	// Trailer
	resp.Trailer, err = fixTrailer(resp.Header, resp.TransferEncoding)
	if err != nil {
		return nil, err
	}

	// Prepare body reader.  ContentLength < 0 means chunked encoding
	// or close connection when finished, since multipart is not supported yet
	switch {
	case chunked(resp.TransferEncoding):
		resp.Body = &body{Reader: newChunkedReader(r), hdr: resp, r: r, closing: resp.Close}
	case resp.ContentLength >= 0:
		resp.Body = &body{Reader: io.LimitReader(r, resp.ContentLength), closing: resp.Close}
	default:
		resp.Body = &body{Reader: r, closing: resp.Close}
	}

	return resp, nil
}

// body turns a Reader into a ReadCloser.
// Close ensures that the body has been fully read
// and then reads the trailer if necessary.
type body struct {
	io.Reader
	hdr     interface{}   // non-nil (Response or Request) value means read trailer
	r       *bufio.Reader // underlying wire-format reader for the trailer
	closing bool          // is the connection to be closed after reading body?
}

func (b *body) Close() os.Error {
	if b.hdr == nil && b.closing {
		// no trailer and closing the connection next.
		// no point in reading to EOF.
		return nil
	}

	trashBuf := make([]byte, 1024) // local for thread safety
	for {
		_, err := b.Read(trashBuf)
		if err == nil {
			continue
		}
		if err == os.EOF {
			break
		}
		return err
	}
	if b.hdr == nil { // not reading trailer
		return nil
	}

	// TODO(petar): Put trailer reader code here

	return nil
}

// RFC2616: Should treat
//	Pragma: no-cache
// like
//	Cache-Control: no-cache
func fixPragmaCacheControl(header map[string]string) {
	if v, present := header["Pragma"]; present && v == "no-cache" {
		if _, presentcc := header["Cache-Control"]; !presentcc {
			header["Cache-Control"] = "no-cache"
		}
	}
}

// Parse the trailer header
func fixTrailer(header map[string]string, te []string) (map[string]string, os.Error) {
	raw, present := header["Trailer"]
	if !present {
		return nil, nil
	}

	header["Trailer"] = "", false
	trailer := make(map[string]string)
	keys := strings.Split(raw, ",", 0)
	for _, key := range keys {
		key = CanonicalHeaderKey(strings.TrimSpace(key))
		switch key {
		case "Transfer-Encoding", "Trailer", "Content-Length":
			return nil, &badStringError{"bad trailer key", key}
		}
		trailer[key] = ""
	}
	if len(trailer) == 0 {
		return nil, nil
	}
	if !chunked(te) {
		// Trailer and no chunking
		return nil, ErrUnexpectedTrailer
	}
	return trailer, nil
}

// Sanitize transfer encoding
func fixTransferEncoding(header map[string]string) ([]string, os.Error) {
	raw, present := header["Transfer-Encoding"]
	if !present {
		return nil, nil
	}

	header["Transfer-Encoding"] = "", false
	encodings := strings.Split(raw, ",", 0)
	te := make([]string, 0, len(encodings))
	// TODO: Even though we only support "identity" and "chunked"
	// encodings, the loop below is designed with foresight. One
	// invariant that must be maintained is that, if present,
	// chunked encoding must always come first.
	for _, encoding := range encodings {
		encoding = strings.ToLower(strings.TrimSpace(encoding))
		// "identity" encoding is not recored
		if encoding == "identity" {
			break
		}
		if encoding != "chunked" {
			return nil, &badStringError{"unsupported transfer encoding", encoding}
		}
		te = te[0 : len(te)+1]
		te[len(te)-1] = encoding
	}
	if len(te) > 1 {
		return nil, &badStringError{"too many transfer encodings", strings.Join(te, ",")}
	}
	if len(te) > 0 {
		// Chunked encoding trumps Content-Length. See RFC 2616
		// Section 4.4. Currently len(te) > 0 implies chunked
		// encoding.
		header["Content-Length"] = "", false
		return te, nil
	}

	return nil, nil
}

func noBodyExpected(requestMethod string) bool {
	return requestMethod == "HEAD"
}

// Determine the expected body length, using RFC 2616 Section 4.4. This
// function is not a method, because ultimately it should be shared by
// ReadResponse and ReadRequest.
func fixLength(status int, requestMethod string, header map[string]string, te []string) (int64, os.Error) {

	// Logic based on response type or status
	if noBodyExpected(requestMethod) {
		return 0, nil
	}
	if status/100 == 1 {
		return 0, nil
	}
	switch status {
	case 204, 304:
		return 0, nil
	}

	// Logic based on Transfer-Encoding
	if chunked(te) {
		return -1, nil
	}

	// Logic based on Content-Length
	if cl, present := header["Content-Length"]; present {
		cl = strings.TrimSpace(cl)
		if cl != "" {
			n, err := strconv.Atoi64(cl)
			if err != nil || n < 0 {
				return -1, &badStringError{"bad Content-Length", cl}
			}
			return n, nil
		} else {
			header["Content-Length"] = "", false
		}
	}

	// Logic based on media type. The purpose of the following code is just
	// to detect whether the unsupported "multipart/byteranges" is being
	// used. A proper Content-Type parser is needed in the future.
	if ct, present := header["Content-Type"]; present {
		ct = strings.ToLower(ct)
		if strings.Index(ct, "multipart/byteranges") >= 0 {
			return -1, ErrNotSupported
		}
	}


	// Logic based on close
	return -1, nil
}

// Determine whether to hang up after sending a request and body, or
// receiving a response and body
func shouldClose(major, minor int, header map[string]string) bool {
	if major < 1 || (major == 1 && minor < 1) {
		return true
	} else if v, present := header["Connection"]; present {
		// TODO: Should split on commas, toss surrounding white space,
		// and check each field.
		if v == "close" {
			return true
		}
	}
	return false
}

// Checks whether chunked is part of the encodings stack
func chunked(te []string) bool { return len(te) > 0 && te[0] == "chunked" }

// AddHeader adds a value under the given key.  Keys are not case sensitive.
func (r *Response) AddHeader(key, value string) {
	key = CanonicalHeaderKey(key)

	oldValues, oldValuesPresent := r.Header[key]
	if oldValuesPresent {
		r.Header[key] = oldValues + "," + value
	} else {
		r.Header[key] = value
	}
}

// GetHeader returns the value of the response header with the given
// key, and true.  If there were multiple headers with this key, their
// values are concatenated, with a comma delimiter.  If there were no
// response headers with the given key, it returns the empty string and
// false.  Keys are not case sensitive.
func (r *Response) GetHeader(key string) (value string) {
	value, _ = r.Header[CanonicalHeaderKey(key)]
	return
}

// ProtoAtLeast returns whether the HTTP protocol used
// in the response is at least major.minor.
func (r *Response) ProtoAtLeast(major, minor int) bool {
	return r.ProtoMajor > major ||
		r.ProtoMajor == major && r.ProtoMinor >= minor
}

// Writes the response (header, body and trailer) in wire format. This method
// consults the following fields of resp:
//
//  StatusCode
//  ProtoMajor
//  ProtoMinor
//  RequestMethod
//  TransferEncoding
//  Trailer
//  Body
//  ContentLength
//  Header, values for non-canonical keys will have unpredictable behavior
//
func (resp *Response) Write(w io.Writer) os.Error {

	// RequestMethod should be upper-case
	resp.RequestMethod = strings.ToUpper(resp.RequestMethod)

	// Status line
	text, ok := statusText[resp.StatusCode]
	if !ok {
		text = "status code " + strconv.Itoa(resp.StatusCode)
	}
	io.WriteString(w, "HTTP/"+strconv.Itoa(resp.ProtoMajor)+".")
	io.WriteString(w, strconv.Itoa(resp.ProtoMinor)+" ")
	io.WriteString(w, strconv.Itoa(resp.StatusCode)+" "+text+"\r\n")

	// Sanitize the field triple (Body, ContentLength, TransferEncoding)
	if noBodyExpected(resp.RequestMethod) {
		resp.Body = nil
		resp.TransferEncoding = nil
		// resp.ContentLength is expected to hold Content-Length
		if resp.ContentLength < 0 {
			return ErrMissingContentLength
		}
	} else {
		if !resp.ProtoAtLeast(1, 1) || resp.Body == nil {
			resp.TransferEncoding = nil
		}
		if chunked(resp.TransferEncoding) {
			resp.ContentLength = -1
		} else if resp.Body == nil { // no chunking, no body
			resp.ContentLength = 0
		}
	}

	// Write Content-Length and/or Transfer-Encoding whose values are a
	// function of the sanitized field triple (Body, ContentLength,
	// TransferEncoding)
	if chunked(resp.TransferEncoding) {
		io.WriteString(w, "Transfer-Encoding: chunked\r\n")
	} else {
		if resp.ContentLength > 0 || resp.RequestMethod == "HEAD" {
			io.WriteString(w, "Content-Length: ")
			io.WriteString(w, strconv.Itoa64(resp.ContentLength)+"\r\n")
		}
	}
	if resp.Header != nil {
		resp.Header["Content-Length"] = "", false
		resp.Header["Transfer-Encoding"] = "", false
	}

	// Sanitize Trailer
	if !chunked(resp.TransferEncoding) {
		resp.Trailer = nil
	} else if resp.Trailer != nil {
		// TODO: At some point, there should be a generic mechanism for
		// writing long headers, using HTTP line splitting
		io.WriteString(w, "Trailer: ")
		needComma := false
		for k, _ := range resp.Trailer {
			k = CanonicalHeaderKey(k)
			switch k {
			case "Transfer-Encoding", "Trailer", "Content-Length":
				return &badStringError{"invalid Trailer key", k}
			}
			if needComma {
				io.WriteString(w, ",")
			}
			io.WriteString(w, k)
			needComma = true
		}
		io.WriteString(w, "\r\n")
	}
	if resp.Header != nil {
		resp.Header["Trailer"] = "", false
	}

	// Rest of header
	for k, v := range resp.Header {
		io.WriteString(w, k+": "+v+"\r\n")
	}

	// End-of-header
	io.WriteString(w, "\r\n")

	// Write body
	if resp.Body != nil {
		var err os.Error
		if chunked(resp.TransferEncoding) {
			cw := NewChunkedWriter(w)
			_, err = io.Copy(cw, resp.Body)
			if err == nil {
				err = cw.Close()
			}
		} else {
			_, err = io.Copy(w, io.LimitReader(resp.Body, resp.ContentLength))
		}
		if err != nil {
			return err
		}
		if err = resp.Body.Close(); err != nil {
			return err
		}
	}

	// TODO(petar): Place trailer writer code here.
	if chunked(resp.TransferEncoding) {
		// Last chunk, empty trailer
		io.WriteString(w, "\r\n")
	}

	// Success
	return nil
}
