package smtpserver

import (
	"fmt"
	"os"

	"github.com/mjl-/mox/dsn"
	"github.com/mjl-/mox/queue"
	"github.com/mjl-/mox/smtp"
	"github.com/mjl-/mox/store"
)

// compose dsn message and add it to the queue for delivery to rcptTo.
func queueDSN(c *conn, rcptTo smtp.Path, m dsn.Message) error {
	buf, err := m.Compose(c.log, false)
	if err != nil {
		return err
	}
	var bufUTF8 []byte
	if c.smtputf8 {
		bufUTF8, err = m.Compose(c.log, true)
		if err != nil {
			c.log.Errorx("composing dsn with utf-8 for incoming delivery for unknown user, continuing with ascii-only dsn", err)
		}
	}

	f, err := store.CreateMessageTemp("smtp-dsn")
	if err != nil {
		return fmt.Errorf("creating temp file: %w", err)
	}
	defer func() {
		if f != nil {
			err := os.Remove(f.Name())
			c.log.Check(err, "removing temporary dsn message file")
			err = f.Close()
			c.log.Check(err, "closing temporary dsn message file")
		}
	}()
	if _, err := f.Write([]byte(buf)); err != nil {
		return fmt.Errorf("writing dsn file: %w", err)
	}

	// Queue DSN with null reverse path so failures to deliver will eventually drop the
	// message instead of causing delivery loops.
	// ../rfc/3464:433
	const has8bit = false
	const smtputf8 = false
	if err := queue.Add(c.log, "", smtp.Path{}, rcptTo, has8bit, smtputf8, int64(len(buf)), nil, f, bufUTF8, true); err != nil {
		return err
	}
	err = f.Close()
	c.log.Check(err, "closing dsn file")
	f = nil
	return nil
}
