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

package tls

import (
	"fmt"
	"hash"
	"io"
)

// writerEnableApplicationData is a message which instructs recordWriter to
// start reading and transmitting data from the application data channel.
type writerEnableApplicationData struct{}

// writerChangeCipherSpec updates the encryption and MAC functions and resets
// the sequence count.
type writerChangeCipherSpec struct {
	encryptor encryptor
	mac       hash.Hash
}

// writerSetVersion sets the version number bytes that we included in the
// record header for future records.
type writerSetVersion struct {
	major, minor uint8
}

// A recordWriter accepts messages from the handshake processor and
// application data. It writes them to the outgoing connection and blocks on
// writing. It doesn't read from the application data channel until the
// handshake processor has signaled that the handshake is complete.
type recordWriter struct {
	writer       io.Writer
	encryptor    encryptor
	mac          hash.Hash
	seqNum       uint64
	major, minor uint8
	shutdown     bool
	appChan      <-chan []byte
	controlChan  <-chan interface{}
	header       [13]byte
}

func (w *recordWriter) loop(writer io.Writer, appChan <-chan []byte, controlChan <-chan interface{}) {
	w.writer = writer
	w.encryptor = nop{}
	w.mac = nop{}
	w.appChan = appChan
	w.controlChan = controlChan

	for !w.shutdown {
		msg := <-controlChan
		if _, ok := msg.(writerEnableApplicationData); ok {
			break
		}
		w.processControlMessage(msg)
	}

	for !w.shutdown {
		// Always process control messages first.
		if controlMsg, ok := <-controlChan; ok {
			w.processControlMessage(controlMsg)
			continue
		}

		select {
		case controlMsg := <-controlChan:
			w.processControlMessage(controlMsg)
		case appMsg := <-appChan:
			w.processAppMessage(appMsg)
		}
	}

	if !closed(appChan) {
		go func() {
			for _ = range appChan {
			}
		}()
	}
	if !closed(controlChan) {
		go func() {
			for _ = range controlChan {
			}
		}()
	}
}

// fillMACHeader generates a MAC header. See RFC 4346, section 6.2.3.1.
func fillMACHeader(header *[13]byte, seqNum uint64, length int, r *record) {
	header[0] = uint8(seqNum >> 56)
	header[1] = uint8(seqNum >> 48)
	header[2] = uint8(seqNum >> 40)
	header[3] = uint8(seqNum >> 32)
	header[4] = uint8(seqNum >> 24)
	header[5] = uint8(seqNum >> 16)
	header[6] = uint8(seqNum >> 8)
	header[7] = uint8(seqNum)
	header[8] = uint8(r.contentType)
	header[9] = r.major
	header[10] = r.minor
	header[11] = uint8(length >> 8)
	header[12] = uint8(length)
}

func (w *recordWriter) writeRecord(r *record) {
	w.mac.Reset()

	fillMACHeader(&w.header, w.seqNum, len(r.payload), r)

	w.mac.Write(w.header[0:13])
	w.mac.Write(r.payload)
	macBytes := w.mac.Sum()

	w.encryptor.XORKeyStream(r.payload)
	w.encryptor.XORKeyStream(macBytes)

	length := len(r.payload) + len(macBytes)
	w.header[11] = uint8(length >> 8)
	w.header[12] = uint8(length)
	w.writer.Write(w.header[8:13])
	w.writer.Write(r.payload)
	w.writer.Write(macBytes)

	w.seqNum++
}

func (w *recordWriter) processControlMessage(controlMsg interface{}) {
	if controlMsg == nil {
		w.shutdown = true
		return
	}

	switch msg := controlMsg.(type) {
	case writerChangeCipherSpec:
		w.writeRecord(&record{recordTypeChangeCipherSpec, w.major, w.minor, []byte{0x01}})
		w.encryptor = msg.encryptor
		w.mac = msg.mac
		w.seqNum = 0
	case writerSetVersion:
		w.major = msg.major
		w.minor = msg.minor
	case alert:
		w.writeRecord(&record{recordTypeAlert, w.major, w.minor, []byte{byte(msg.level), byte(msg.error)}})
	case handshakeMessage:
		// TODO(agl): marshal may return a slice too large for a single record.
		w.writeRecord(&record{recordTypeHandshake, w.major, w.minor, msg.marshal()})
	default:
		fmt.Printf("processControlMessage: unknown %#v\n", msg)
	}
}

func (w *recordWriter) processAppMessage(appMsg []byte) {
	if closed(w.appChan) {
		w.writeRecord(&record{recordTypeApplicationData, w.major, w.minor, []byte{byte(alertCloseNotify)}})
		w.shutdown = true
		return
	}

	var done int
	for done < len(appMsg) {
		todo := len(appMsg)
		if todo > maxTLSPlaintext {
			todo = maxTLSPlaintext
		}
		w.writeRecord(&record{recordTypeApplicationData, w.major, w.minor, appMsg[done : done+todo]})
		done += todo
	}
}
