// Copyright 2015 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 quotedprintable

import "io"

const lineMaxLen = 76

// A Writer is a quoted-printable writer that implements io.WriteCloser.
type Writer struct {
	// Binary mode treats the writer's input as pure binary and processes end of
	// line bytes as binary data.
	Binary bool

	w    io.Writer
	i    int
	line [78]byte
	cr   bool
}

// NewWriter returns a new Writer that writes to w.
func NewWriter(w io.Writer) *Writer {
	return &Writer{w: w}
}

// Write encodes p using quoted-printable encoding and writes it to the
// underlying io.Writer. It limits line length to 76 characters. The encoded
// bytes are not necessarily flushed until the Writer is closed.
func (w *Writer) Write(p []byte) (n int, err error) {
	for i, b := range p {
		switch {
		// Simple writes are done in batch.
		case b >= '!' && b <= '~' && b != '=':
			continue
		case isWhitespace(b) || !w.Binary && (b == '\n' || b == '\r'):
			continue
		}

		if i > n {
			if err := w.write(p[n:i]); err != nil {
				return n, err
			}
			n = i
		}

		if err := w.encode(b); err != nil {
			return n, err
		}
		n++
	}

	if n == len(p) {
		return n, nil
	}

	if err := w.write(p[n:]); err != nil {
		return n, err
	}

	return len(p), nil
}

// Close closes the Writer, flushing any unwritten data to the underlying
// io.Writer, but does not close the underlying io.Writer.
func (w *Writer) Close() error {
	if err := w.checkLastByte(); err != nil {
		return err
	}

	return w.flush()
}

// write limits text encoded in quoted-printable to 76 characters per line.
func (w *Writer) write(p []byte) error {
	for _, b := range p {
		if b == '\n' || b == '\r' {
			// If the previous byte was \r, the CRLF has already been inserted.
			if w.cr && b == '\n' {
				w.cr = false
				continue
			}

			if b == '\r' {
				w.cr = true
			}

			if err := w.checkLastByte(); err != nil {
				return err
			}
			if err := w.insertCRLF(); err != nil {
				return err
			}
			continue
		}

		if w.i == lineMaxLen-1 {
			if err := w.insertSoftLineBreak(); err != nil {
				return err
			}
		}

		w.line[w.i] = b
		w.i++
		w.cr = false
	}

	return nil
}

func (w *Writer) encode(b byte) error {
	if lineMaxLen-1-w.i < 3 {
		if err := w.insertSoftLineBreak(); err != nil {
			return err
		}
	}

	w.line[w.i] = '='
	w.line[w.i+1] = upperhex[b>>4]
	w.line[w.i+2] = upperhex[b&0x0f]
	w.i += 3

	return nil
}

const upperhex = "0123456789ABCDEF"

// checkLastByte encodes the last buffered byte if it is a space or a tab.
func (w *Writer) checkLastByte() error {
	if w.i == 0 {
		return nil
	}

	b := w.line[w.i-1]
	if isWhitespace(b) {
		w.i--
		if err := w.encode(b); err != nil {
			return err
		}
	}

	return nil
}

func (w *Writer) insertSoftLineBreak() error {
	w.line[w.i] = '='
	w.i++

	return w.insertCRLF()
}

func (w *Writer) insertCRLF() error {
	w.line[w.i] = '\r'
	w.line[w.i+1] = '\n'
	w.i += 2

	return w.flush()
}

func (w *Writer) flush() error {
	if _, err := w.w.Write(w.line[:w.i]); err != nil {
		return err
	}

	w.i = 0
	return nil
}

func isWhitespace(b byte) bool {
	return b == ' ' || b == '\t'
}
