// 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;
	}
}
