package wire

import (
	

	
	
)

// A CryptoFrame is a CRYPTO frame
type CryptoFrame struct {
	Offset protocol.ByteCount
	Data   []byte
}

func parseCryptoFrame( []byte,  protocol.Version) (*CryptoFrame, int, error) {
	 := len()
	 := &CryptoFrame{}
	, ,  := quicvarint.Parse()
	if  != nil {
		return nil, 0, replaceUnexpectedEOF()
	}
	 = [:]
	.Offset = protocol.ByteCount()
	, ,  := quicvarint.Parse()
	if  != nil {
		return nil, 0, replaceUnexpectedEOF()
	}
	 = [:]
	if  > uint64(len()) {
		return nil, 0, io.EOF
	}
	if  != 0 {
		.Data = make([]byte, )
		copy(.Data, )
	}
	return ,  - len() + int(), nil
}

func ( *CryptoFrame) ( []byte,  protocol.Version) ([]byte, error) {
	 = append(, cryptoFrameType)
	 = quicvarint.Append(, uint64(.Offset))
	 = quicvarint.Append(, uint64(len(.Data)))
	 = append(, .Data...)
	return , nil
}

// Length of a written frame
func ( *CryptoFrame) ( protocol.Version) protocol.ByteCount {
	return protocol.ByteCount(1 + quicvarint.Len(uint64(.Offset)) + quicvarint.Len(uint64(len(.Data))) + len(.Data))
}

// MaxDataLen returns the maximum data length
func ( *CryptoFrame) ( protocol.ByteCount) protocol.ByteCount {
	// pretend that the data size will be 1 bytes
	// if it turns out that varint encoding the length will consume 2 bytes, we need to adjust the data length afterwards
	 := protocol.ByteCount(1 + quicvarint.Len(uint64(.Offset)) + 1)
	if  >  {
		return 0
	}
	 :=  - 
	if quicvarint.Len(uint64()) != 1 {
		--
	}
	return 
}

// MaybeSplitOffFrame splits a frame such that it is not bigger than n bytes.
// It returns if the frame was actually split.
// The frame might not be split if:
// * the size is large enough to fit the whole frame
// * the size is too small to fit even a 1-byte frame. In that case, the frame returned is nil.
func ( *CryptoFrame) ( protocol.ByteCount,  protocol.Version) (*CryptoFrame, bool /* was splitting required */) {
	if .Length() <=  {
		return nil, false
	}

	 := .MaxDataLen()
	if  == 0 {
		return nil, true
	}

	 := protocol.ByteCount(len(.Data)) - 

	 := &CryptoFrame{}
	.Offset = .Offset
	.Data = make([]byte, )

	// swap the data slices
	.Data, .Data = .Data, .Data

	copy(.Data, .Data[:])
	.Data = .Data[:]
	.Offset += 

	return , true
}