// Copyright 2011 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 spdy implements the SPDY protocol (currently SPDY/3), described in
// http://www.chromium.org/spdy/spdy-protocol/spdy-protocol-draft3.
package spdy // import "golang.org/x/net/spdy"

import (
	"bytes"
	"compress/zlib"
	"io"
	"net/http"
)

// Version is the protocol version number that this package implements.
const Version = 3

// ControlFrameType stores the type field in a control frame header.
type ControlFrameType uint16

const (
	TypeSynStream    ControlFrameType = 0x0001
	TypeSynReply                      = 0x0002
	TypeRstStream                     = 0x0003
	TypeSettings                      = 0x0004
	TypePing                          = 0x0006
	TypeGoAway                        = 0x0007
	TypeHeaders                       = 0x0008
	TypeWindowUpdate                  = 0x0009
)

// ControlFlags are the flags that can be set on a control frame.
type ControlFlags uint8

const (
	ControlFlagFin                   ControlFlags = 0x01
	ControlFlagUnidirectional                     = 0x02
	ControlFlagSettingsClearSettings              = 0x01
)

// DataFlags are the flags that can be set on a data frame.
type DataFlags uint8

const (
	DataFlagFin DataFlags = 0x01
)

// MaxDataLength is the maximum number of bytes that can be stored in one frame.
const MaxDataLength = 1<<24 - 1

// headerValueSepator separates multiple header values.
const headerValueSeparator = "\x00"

// Frame is a single SPDY frame in its unpacked in-memory representation. Use
// Framer to read and write it.
type Frame interface {
	write(f *Framer) error
}

// ControlFrameHeader contains all the fields in a control frame header,
// in its unpacked in-memory representation.
type ControlFrameHeader struct {
	// Note, high bit is the "Control" bit.
	version   uint16 // spdy version number
	frameType ControlFrameType
	Flags     ControlFlags
	length    uint32 // length of data field
}

type controlFrame interface {
	Frame
	read(h ControlFrameHeader, f *Framer) error
}

// StreamId represents a 31-bit value identifying the stream.
type StreamId uint32

// SynStreamFrame is the unpacked, in-memory representation of a SYN_STREAM
// frame.
type SynStreamFrame struct {
	CFHeader             ControlFrameHeader
	StreamId             StreamId
	AssociatedToStreamId StreamId // stream id for a stream which this stream is associated to
	Priority             uint8    // priority of this frame (3-bit)
	Slot                 uint8    // index in the server's credential vector of the client certificate
	Headers              http.Header
}

// SynReplyFrame is the unpacked, in-memory representation of a SYN_REPLY frame.
type SynReplyFrame struct {
	CFHeader ControlFrameHeader
	StreamId StreamId
	Headers  http.Header
}

// RstStreamStatus represents the status that led to a RST_STREAM.
type RstStreamStatus uint32

const (
	ProtocolError RstStreamStatus = iota + 1
	InvalidStream
	RefusedStream
	UnsupportedVersion
	Cancel
	InternalError
	FlowControlError
	StreamInUse
	StreamAlreadyClosed
	InvalidCredentials
	FrameTooLarge
)

// RstStreamFrame is the unpacked, in-memory representation of a RST_STREAM
// frame.
type RstStreamFrame struct {
	CFHeader ControlFrameHeader
	StreamId StreamId
	Status   RstStreamStatus
}

// SettingsFlag represents a flag in a SETTINGS frame.
type SettingsFlag uint8

const (
	FlagSettingsPersistValue SettingsFlag = 0x1
	FlagSettingsPersisted                 = 0x2
)

// SettingsFlag represents the id of an id/value pair in a SETTINGS frame.
type SettingsId uint32

const (
	SettingsUploadBandwidth SettingsId = iota + 1
	SettingsDownloadBandwidth
	SettingsRoundTripTime
	SettingsMaxConcurrentStreams
	SettingsCurrentCwnd
	SettingsDownloadRetransRate
	SettingsInitialWindowSize
	SettingsClientCretificateVectorSize
)

// SettingsFlagIdValue is the unpacked, in-memory representation of the
// combined flag/id/value for a setting in a SETTINGS frame.
type SettingsFlagIdValue struct {
	Flag  SettingsFlag
	Id    SettingsId
	Value uint32
}

// SettingsFrame is the unpacked, in-memory representation of a SPDY
// SETTINGS frame.
type SettingsFrame struct {
	CFHeader     ControlFrameHeader
	FlagIdValues []SettingsFlagIdValue
}

// PingFrame is the unpacked, in-memory representation of a PING frame.
type PingFrame struct {
	CFHeader ControlFrameHeader
	Id       uint32 // unique id for this ping, from server is even, from client is odd.
}

// GoAwayStatus represents the status in a GoAwayFrame.
type GoAwayStatus uint32

const (
	GoAwayOK GoAwayStatus = iota
	GoAwayProtocolError
	GoAwayInternalError
)

// GoAwayFrame is the unpacked, in-memory representation of a GOAWAY frame.
type GoAwayFrame struct {
	CFHeader         ControlFrameHeader
	LastGoodStreamId StreamId // last stream id which was accepted by sender
	Status           GoAwayStatus
}

// HeadersFrame is the unpacked, in-memory representation of a HEADERS frame.
type HeadersFrame struct {
	CFHeader ControlFrameHeader
	StreamId StreamId
	Headers  http.Header
}

// WindowUpdateFrame is the unpacked, in-memory representation of a
// WINDOW_UPDATE frame.
type WindowUpdateFrame struct {
	CFHeader        ControlFrameHeader
	StreamId        StreamId
	DeltaWindowSize uint32 // additional number of bytes to existing window size
}

// TODO: Implement credential frame and related methods.

// DataFrame is the unpacked, in-memory representation of a DATA frame.
type DataFrame struct {
	// Note, high bit is the "Control" bit. Should be 0 for data frames.
	StreamId StreamId
	Flags    DataFlags
	Data     []byte // payload data of this frame
}

// A SPDY specific error.
type ErrorCode string

const (
	UnlowercasedHeaderName     ErrorCode = "header was not lowercased"
	DuplicateHeaders                     = "multiple headers with same name"
	WrongCompressedPayloadSize           = "compressed payload size was incorrect"
	UnknownFrameType                     = "unknown frame type"
	InvalidControlFrame                  = "invalid control frame"
	InvalidDataFrame                     = "invalid data frame"
	InvalidHeaderPresent                 = "frame contained invalid header"
	ZeroStreamId                         = "stream id zero is disallowed"
)

// Error contains both the type of error and additional values. StreamId is 0
// if Error is not associated with a stream.
type Error struct {
	Err      ErrorCode
	StreamId StreamId
}

func (e *Error) Error() string {
	return string(e.Err)
}

var invalidReqHeaders = map[string]bool{
	"Connection":        true,
	"Host":              true,
	"Keep-Alive":        true,
	"Proxy-Connection":  true,
	"Transfer-Encoding": true,
}

var invalidRespHeaders = map[string]bool{
	"Connection":        true,
	"Keep-Alive":        true,
	"Proxy-Connection":  true,
	"Transfer-Encoding": true,
}

// Framer handles serializing/deserializing SPDY frames, including compressing/
// decompressing payloads.
type Framer struct {
	headerCompressionDisabled bool
	w                         io.Writer
	headerBuf                 *bytes.Buffer
	headerCompressor          *zlib.Writer
	r                         io.Reader
	headerReader              io.LimitedReader
	headerDecompressor        io.ReadCloser
}

// NewFramer allocates a new Framer for a given SPDY connection, represented by
// a io.Writer and io.Reader. Note that Framer will read and write individual fields
// from/to the Reader and Writer, so the caller should pass in an appropriately
// buffered implementation to optimize performance.
func NewFramer(w io.Writer, r io.Reader) (*Framer, error) {
	compressBuf := new(bytes.Buffer)
	compressor, err := zlib.NewWriterLevelDict(compressBuf, zlib.BestCompression, []byte(headerDictionary))
	if err != nil {
		return nil, err
	}
	framer := &Framer{
		w:                w,
		headerBuf:        compressBuf,
		headerCompressor: compressor,
		r:                r,
	}
	return framer, nil
}
