// Copyright 2015 The Vanadium 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 serialization

import (
	"bytes"
	"crypto/sha256"
	"encoding/binary"
	"hash"
	"io"

	"v.io/v23/security"
	"v.io/v23/verror"
	"v.io/v23/vom"
)

var (
	errCantBeNilSigner = verror.Register(pkgPath+".errCantBeNilSigner", verror.NoRetry, "{1:}{2:} data:{3} signature:{4} signer:{5} cannot be nil{:_}")
	errCantSign        = verror.Register(pkgPath+".errCantSign", verror.NoRetry, "{1:}{2:} signing failed{:_}")
)

const defaultChunkSizeBytes = 1 << 20

// signingWriter implements io.WriteCloser.
type signingWriter struct {
	data      io.WriteCloser
	signature io.WriteCloser
	signer    Signer

	chunkSizeBytes int64
	curChunk       bytes.Buffer
	signatureHash  hash.Hash
	sigEnc         *vom.Encoder
}

func (w *signingWriter) Write(p []byte) (int, error) {
	bytesWritten := 0
	for len(p) > 0 {
		pLimited := p
		curChunkFreeBytes := w.chunkSizeBytes - int64(w.curChunk.Len())
		if int64(len(pLimited)) > curChunkFreeBytes {
			pLimited = pLimited[:curChunkFreeBytes]
		}

		n, err := w.curChunk.Write(pLimited)
		bytesWritten = bytesWritten + n
		if err != nil {
			return bytesWritten, err
		}
		p = p[n:]

		if err := w.commitChunk(false); err != nil {
			return bytesWritten, err
		}
	}
	return bytesWritten, nil
}

func (w *signingWriter) Close() error {
	if w.curChunk.Len() > 0 {
		if err := w.commitChunk(true); err != nil {
			defer w.close()
			return err
		}
	}
	if err := w.commitSignature(); err != nil {
		defer w.close()
		return err
	}
	return w.close()
}

// Options specifies parameters to tune a SigningWriteCloser.
type Options struct {
	// ChunkSizeBytes controls the maximum amount of memory devoted to buffering
	// data provided to Write calls. See NewSigningWriteCloser.
	ChunkSizeBytes int64
}

// Signer is the interface for digital signature operations used by NewSigningWriteCloser.
type Signer interface {
	Sign(message []byte) (security.Signature, error)
	PublicKey() security.PublicKey
}

// NewSigningWriteCloser returns an io.WriteCloser that writes data along
// with an appropriate signature that establishes the integrity and
// authenticity of the data. It behaves as follows:
// * A Write call writes chunks (of size provided by the Options or 1MB by default)
//   of data to the provided data WriteCloser and a hash of the chunks to the provided
//   signature WriteCloser.
// * A Close call writes a signature (computed using the provided signer) of
//   all the hashes written, and then closes the data and signature WriteClosers.
func NewSigningWriteCloser(data, signature io.WriteCloser, s Signer, opts *Options) (io.WriteCloser, error) {
	if (data == nil) || (signature == nil) || (s == nil) {
		return nil, verror.New(errCantBeNilSigner, nil, data, signature, s)
	}
	enc := vom.NewEncoder(signature)
	w := &signingWriter{data: data, signature: signature, signer: s, signatureHash: sha256.New(), chunkSizeBytes: defaultChunkSizeBytes, sigEnc: enc}

	if opts != nil {
		w.chunkSizeBytes = opts.ChunkSizeBytes
	}

	if err := w.commitHeader(); err != nil {
		return nil, err
	}
	return w, nil
}

func (w *signingWriter) commitHeader() error {
	if err := binary.Write(w.signatureHash, binary.LittleEndian, int64(w.chunkSizeBytes)); err != nil {
		return err
	}
	if err := w.sigEnc.Encode(SignedHeader{w.chunkSizeBytes}); err != nil {
		return err
	}
	return nil
}

func (w *signingWriter) commitChunk(force bool) error {
	if !force && int64(w.curChunk.Len()) < w.chunkSizeBytes {
		return nil
	}

	hashBytes := sha256.Sum256(w.curChunk.Bytes())
	if _, err := io.CopyN(w.data, &w.curChunk, int64(w.curChunk.Len())); err != nil {
		return err
	}
	if _, err := w.signatureHash.Write(hashBytes[:]); err != nil {
		return err
	}
	return w.sigEnc.Encode(SignedDataHash{hashBytes})
}

func (w *signingWriter) commitSignature() error {
	sig, err := w.signer.Sign(w.signatureHash.Sum(nil))
	if err != nil {
		return verror.New(errCantSign, nil, err)
	}

	return w.sigEnc.Encode(SignedDataSignature{sig})
}

func (w *signingWriter) close() error {
	var closeErr error
	if err := w.data.Close(); err != nil && closeErr == nil {
		closeErr = err
	}
	if err := w.signature.Close(); err != nil && closeErr == nil {
		closeErr = err
	}
	return closeErr
}
