// Package gomail provides a simple interface to send emails.
//
// More info on Github: https://github.com/go-gomail/gomail
package gomail

import (
	"bytes"
	"io"
	"io/ioutil"
	"mime"
	"path/filepath"
	"sync"
	"time"

	"gopkg.in/alexcesaro/quotedprintable.v2"
)

// Message represents an email.
type Message struct {
	header      header
	parts       []part
	attachments []*File
	embedded    []*File
	charset     string
	encoding    Encoding
	hEncoder    *quotedprintable.HeaderEncoder
}

type header map[string][]string

type part struct {
	contentType string
	body        *bytes.Buffer
}

// NewMessage creates a new message. It uses UTF-8 and quoted-printable encoding
// by default.
func NewMessage(settings ...MessageSetting) *Message {
	msg := &Message{
		header:   make(header),
		charset:  "UTF-8",
		encoding: QuotedPrintable,
	}

	msg.applySettings(settings)

	var e quotedprintable.Encoding
	if msg.encoding == Base64 {
		e = quotedprintable.B
	} else {
		e = quotedprintable.Q
	}
	msg.hEncoder = e.NewHeaderEncoder(msg.charset)

	return msg
}

func (msg *Message) applySettings(settings []MessageSetting) {
	for _, s := range settings {
		s(msg)
	}
}

// A MessageSetting can be used as an argument in NewMessage to configure an
// email.
type MessageSetting func(msg *Message)

// SetCharset is a message setting to set the charset of the email.
//
// Example:
//
//	msg := gomail.NewMessage(SetCharset("ISO-8859-1"))
func SetCharset(charset string) MessageSetting {
	return func(msg *Message) {
		msg.charset = charset
	}
}

// SetEncoding is a message setting to set the encoding of the email.
//
// Example:
//
//	msg := gomail.NewMessage(SetEncoding(gomail.Base64))
func SetEncoding(enc Encoding) MessageSetting {
	return func(msg *Message) {
		msg.encoding = enc
	}
}

// Encoding represents a MIME encoding scheme like quoted-printable or base64.
type Encoding string

const (
	// QuotedPrintable represents the quoted-printable encoding as defined in
	// RFC 2045.
	QuotedPrintable Encoding = "quoted-printable"
	// Base64 represents the base64 encoding as defined in RFC 2045.
	Base64 Encoding = "base64"
	// Unencoded can be used to avoid encoding the body of an email. The headers
	// will still be encoded using quoted-printable encoding.
	Unencoded Encoding = "8bit"
)

// SetHeader sets a value to the given header field.
func (msg *Message) SetHeader(field string, value ...string) {
	for i := range value {
		value[i] = encodeHeader(msg.hEncoder, value[i])
	}
	msg.header[field] = value
}

// SetHeaders sets the message headers.
//
// Example:
//
//	msg.SetHeaders(map[string][]string{
//		"From":    {"alex@example.com"},
//		"To":      {"bob@example.com", "cora@example.com"},
//		"Subject": {"Hello"},
//	})
func (msg *Message) SetHeaders(h map[string][]string) {
	for k, v := range h {
		msg.SetHeader(k, v...)
	}
}

// SetAddressHeader sets an address to the given header field.
func (msg *Message) SetAddressHeader(field, address, name string) {
	msg.header[field] = []string{msg.FormatAddress(address, name)}
}

// FormatAddress formats an address and a name as a valid RFC 5322 address.
func (msg *Message) FormatAddress(address, name string) string {
	buf := getBuffer()
	defer putBuffer(buf)

	if !quotedprintable.NeedsEncoding(name) {
		quote(buf, name)
	} else {
		var n string
		if hasSpecials(name) {
			n = encodeHeader(quotedprintable.B.NewHeaderEncoder(msg.charset), name)
		} else {
			n = encodeHeader(msg.hEncoder, name)
		}
		buf.WriteString(n)
	}
	buf.WriteString(" <")
	buf.WriteString(address)
	buf.WriteByte('>')

	return buf.String()
}

// SetDateHeader sets a date to the given header field.
func (msg *Message) SetDateHeader(field string, date time.Time) {
	msg.header[field] = []string{msg.FormatDate(date)}
}

// FormatDate formats a date as a valid RFC 5322 date.
func (msg *Message) FormatDate(date time.Time) string {
	return date.Format(time.RFC1123Z)
}

// GetHeader gets a header field.
func (msg *Message) GetHeader(field string) []string {
	return msg.header[field]
}

// DelHeader deletes a header field.
func (msg *Message) DelHeader(field string) {
	delete(msg.header, field)
}

// SetBody sets the body of the message.
func (msg *Message) SetBody(contentType, body string) {
	msg.parts = []part{
		part{
			contentType: contentType,
			body:        bytes.NewBufferString(body),
		},
	}
}

// AddAlternative adds an alternative body to the message. Commonly used to
// send HTML emails that default to the plain text version for backward
// compatibility.
//
// Example:
//
//	msg.SetBody("text/plain", "Hello!")
//	msg.AddAlternative("text/html", "<p>Hello!</p>")
//
// More info: http://en.wikipedia.org/wiki/MIME#Alternative
func (msg *Message) AddAlternative(contentType, body string) {
	msg.parts = append(msg.parts,
		part{
			contentType: contentType,
			body:        bytes.NewBufferString(body),
		},
	)
}

// GetBodyWriter gets a writer that writes to the body. It can be useful with
// the templates from packages text/template or html/template.
//
// Example:
//
//	w := msg.GetBodyWriter("text/plain")
//	t := template.Must(template.New("example").Parse("Hello {{.}}!"))
//	t.Execute(w, "Bob")
func (msg *Message) GetBodyWriter(contentType string) io.Writer {
	buf := new(bytes.Buffer)
	msg.parts = append(msg.parts,
		part{
			contentType: contentType,
			body:        buf,
		},
	)

	return buf
}

// A File represents a file that can be attached or embedded in an email.
type File struct {
	Name      string
	MimeType  string
	Content   []byte
	ContentID string
}

// OpenFile opens a file on disk to create a gomail.File.
func OpenFile(filename string) (*File, error) {
	content, err := readFile(filename)
	if err != nil {
		return nil, err
	}

	f := CreateFile(filepath.Base(filename), content)

	return f, nil
}

// CreateFile creates a gomail.File from the given name and content.
func CreateFile(name string, content []byte) *File {
	mimeType := mime.TypeByExtension(filepath.Ext(name))
	if mimeType == "" {
		mimeType = "application/octet-stream"
	}

	return &File{
		Name:     name,
		MimeType: mimeType,
		Content:  content,
	}
}

// Attach attaches the files to the email.
func (msg *Message) Attach(f ...*File) {
	if msg.attachments == nil {
		msg.attachments = f
	} else {
		msg.attachments = append(msg.attachments, f...)
	}
}

// Embed embeds the images to the email.
//
// Example:
//
//	f, err := gomail.OpenFile("/tmp/image.jpg")
//	if err != nil {
//		panic(err)
//	}
//	msg.Embed(f)
//	msg.SetBody("text/html", `<img src="cid:image.jpg" alt="My image" />`)
func (msg *Message) Embed(image ...*File) {
	if msg.embedded == nil {
		msg.embedded = image
	} else {
		msg.embedded = append(msg.embedded, image...)
	}
}

// Stubbed out for testing.
var readFile = ioutil.ReadFile

func quote(buf *bytes.Buffer, text string) {
	buf.WriteByte('"')
	for i := 0; i < len(text); i++ {
		if text[i] == '\\' || text[i] == '"' {
			buf.WriteByte('\\')
		}
		buf.WriteByte(text[i])
	}
	buf.WriteByte('"')
}

func hasSpecials(text string) bool {
	for i := 0; i < len(text); i++ {
		switch c := text[i]; c {
		case '(', ')', '<', '>', '[', ']', ':', ';', '@', '\\', ',', '.', '"':
			return true
		}
	}

	return false
}

func encodeHeader(enc *quotedprintable.HeaderEncoder, value string) string {
	if !quotedprintable.NeedsEncoding(value) {
		return value
	}

	return enc.Encode(value)
}

var bufPool = sync.Pool{
	New: func() interface{} {
		return new(bytes.Buffer)
	},
}

func getBuffer() *bytes.Buffer {
	return bufPool.Get().(*bytes.Buffer)
}

func putBuffer(buf *bytes.Buffer) {
	if buf.Len() > 1024 {
		return
	}
	buf.Reset()
	bufPool.Put(buf)
}
