// Copyright 2010 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 multipart implements MIME multipart parsing, as defined in RFC
2046.

The implementation is sufficient for HTTP (RFC 2388) and the multipart
bodies generated by popular browsers.
*/
package multipart

import (
	"bufio"
	"bytes"
	"fmt"
	"io"
	"io/ioutil"
	"mime"
	"net/textproto"
	"os"
)

// TODO(bradfitz): inline these once the compiler can inline them in
// read-only situation (such as bytes.HasSuffix)
var lf = []byte("\n")
var crlf = []byte("\r\n")

var emptyParams = make(map[string]string)

// A Part represents a single part in a multipart body.
type Part struct {
	// The headers of the body, if any, with the keys canonicalized
	// in the same fashion that the Go http.Request headers are.
	// i.e. "foo-bar" changes case to "Foo-Bar"
	Header textproto.MIMEHeader

	buffer *bytes.Buffer
	mr     *Reader

	disposition       string
	dispositionParams map[string]string
}

// FormName returns the name parameter if p has a Content-Disposition
// of type "form-data".  Otherwise it returns the empty string.
func (p *Part) FormName() string {
	// See http://tools.ietf.org/html/rfc2183 section 2 for EBNF
	// of Content-Disposition value format.
	if p.dispositionParams == nil {
		p.parseContentDisposition()
	}
	if p.disposition != "form-data" {
		return ""
	}
	return p.dispositionParams["name"]
}

// FileName returns the filename parameter of the Part's
// Content-Disposition header.
func (p *Part) FileName() string {
	if p.dispositionParams == nil {
		p.parseContentDisposition()
	}
	return p.dispositionParams["filename"]
}

func (p *Part) parseContentDisposition() {
	v := p.Header.Get("Content-Disposition")
	p.disposition, p.dispositionParams = mime.ParseMediaType(v)
	if p.dispositionParams == nil {
		p.dispositionParams = emptyParams
	}
}

// NewReader creates a new multipart Reader reading from r using the
// given MIME boundary.
func NewReader(reader io.Reader, boundary string) *Reader {
	b := []byte("\r\n--" + boundary + "--")
	return &Reader{
		bufReader: bufio.NewReader(reader),

		nl:               b[:2],
		nlDashBoundary:   b[:len(b)-2],
		dashBoundaryDash: b[2:],
		dashBoundary:     b[2 : len(b)-2],
	}
}

func newPart(mr *Reader) (*Part, os.Error) {
	bp := &Part{
		Header: make(map[string][]string),
		mr:     mr,
		buffer: new(bytes.Buffer),
	}
	if err := bp.populateHeaders(); err != nil {
		return nil, err
	}
	return bp, nil
}

func (bp *Part) populateHeaders() os.Error {
	r := textproto.NewReader(bp.mr.bufReader)
	header, err := r.ReadMIMEHeader()
	if err == nil {
		bp.Header = header
	}
	return err
}

// Read reads the body of a part, after its headers and before the
// next part (if any) begins.
func (bp *Part) Read(p []byte) (n int, err os.Error) {
	if bp.buffer.Len() >= len(p) {
		// Internal buffer of unconsumed data is large enough for
		// the read request.  No need to parse more at the moment.
		return bp.buffer.Read(p)
	}
	peek, err := bp.mr.bufReader.Peek(4096) // TODO(bradfitz): add buffer size accessor
	unexpectedEof := err == os.EOF
	if err != nil && !unexpectedEof {
		return 0, fmt.Errorf("multipart: Part Read: %v", err)
	}
	if peek == nil {
		panic("nil peek buf")
	}

	// Search the peek buffer for "\r\n--boundary". If found,
	// consume everything up to the boundary. If not, consume only
	// as much of the peek buffer as cannot hold the boundary
	// string.
	nCopy := 0
	foundBoundary := false
	if idx := bytes.Index(peek, bp.mr.nlDashBoundary); idx != -1 {
		nCopy = idx
		foundBoundary = true
	} else if safeCount := len(peek) - len(bp.mr.nlDashBoundary); safeCount > 0 {
		nCopy = safeCount
	} else if unexpectedEof {
		// If we've run out of peek buffer and the boundary
		// wasn't found (and can't possibly fit), we must have
		// hit the end of the file unexpectedly.
		return 0, io.ErrUnexpectedEOF
	}
	if nCopy > 0 {
		if _, err := io.Copyn(bp.buffer, bp.mr.bufReader, int64(nCopy)); err != nil {
			return 0, err
		}
	}
	n, err = bp.buffer.Read(p)
	if err == os.EOF && !foundBoundary {
		// If the boundary hasn't been reached there's more to
		// read, so don't pass through an EOF from the buffer
		err = nil
	}
	return
}

func (bp *Part) Close() os.Error {
	io.Copy(ioutil.Discard, bp)
	return nil
}

// Reader is an iterator over parts in a MIME multipart body.
// Reader's underlying parser consumes its input as needed.  Seeking
// isn't supported.
type Reader struct {
	bufReader *bufio.Reader

	currentPart *Part
	partsRead   int

	nl, nlDashBoundary, dashBoundaryDash, dashBoundary []byte
}

// NextPart returns the next part in the multipart or an error.
// When there are no more parts, the error os.EOF is returned.
func (mr *Reader) NextPart() (*Part, os.Error) {
	if mr.currentPart != nil {
		mr.currentPart.Close()
	}

	expectNewPart := false
	for {
		line, err := mr.bufReader.ReadSlice('\n')
		if err != nil {
			return nil, fmt.Errorf("multipart: NextPart: %v", err)
		}

		if mr.isBoundaryDelimiterLine(line) {
			mr.partsRead++
			bp, err := newPart(mr)
			if err != nil {
				return nil, err
			}
			mr.currentPart = bp
			return bp, nil
		}

		if hasPrefixThenNewline(line, mr.dashBoundaryDash) {
			// Expected EOF
			return nil, os.EOF
		}

		if expectNewPart {
			return nil, fmt.Errorf("multipart: expecting a new Part; got line %q", string(line))
		}

		if mr.partsRead == 0 {
			// skip line
			continue
		}

		// Consume the "\n" or "\r\n" separator between the
		// body of the previous part and the boundary line we
		// now expect will follow. (either a new part or the
		// end boundary)
		if bytes.Equal(line, mr.nl) {
			expectNewPart = true
			continue
		}

		return nil, fmt.Errorf("multipart: unexpected line in Next(): %q", line)
	}
	panic("unreachable")
}

func (mr *Reader) isBoundaryDelimiterLine(line []byte) bool {
	// http://tools.ietf.org/html/rfc2046#section-5.1
	//   The boundary delimiter line is then defined as a line
	//   consisting entirely of two hyphen characters ("-",
	//   decimal value 45) followed by the boundary parameter
	//   value from the Content-Type header field, optional linear
	//   whitespace, and a terminating CRLF.
	if !bytes.HasPrefix(line, mr.dashBoundary) {
		return false
	}
	if bytes.HasSuffix(line, mr.nl) {
		return onlyHorizontalWhitespace(line[len(mr.dashBoundary) : len(line)-len(mr.nl)])
	}
	// Violate the spec and also support newlines without the
	// carriage return...
	if mr.partsRead == 0 && bytes.HasSuffix(line, lf) {
		if onlyHorizontalWhitespace(line[len(mr.dashBoundary) : len(line)-1]) {
			mr.nl = mr.nl[1:]
			mr.nlDashBoundary = mr.nlDashBoundary[1:]
			return true
		}
	}
	return false
}

func onlyHorizontalWhitespace(s []byte) bool {
	for _, b := range s {
		if b != ' ' && b != '\t' {
			return false
		}
	}
	return true
}

func hasPrefixThenNewline(s, prefix []byte) bool {
	return bytes.HasPrefix(s, prefix) &&
		(len(s) == len(prefix)+1 && s[len(s)-1] == '\n' ||
			len(s) == len(prefix)+2 && bytes.HasSuffix(s, crlf))
}
