package feedback

import (
	"path/filepath"
	"strings"
)

// maxAttachmentBytes caps a single attachment's raw size. Chosen to fit, with the
// message text and the FlatBuffers framing, under the gateway's 1 MiB edge body
// cap, so the whole submit request passes without weakening that cap.
const maxAttachmentBytes = 1_000_000

// allowedExt is the attachment extension allow-list. It is mirrored on the UI as a
// pre-upload gate; the server re-checks here as the trust boundary (metadata only,
// the file content is never parsed). Images render inline in the console; the rest
// are download-only.
var allowedExt = map[string]bool{
	"png": true, "jpg": true, "jpeg": true, "webp": true, "gif": true, // images
	"pdf": true, "txt": true, "log": true, "doc": true, "docx": true,
	"rtf": true, "zip": true, "gz": true, "7z": true,
}

// imageType maps an image extension to the content-type the console serves it with
// (loaded only via <img>, which never executes, so a renamed non-image is inert).
var imageType = map[string]string{
	"png": "image/png", "jpg": "image/jpeg", "jpeg": "image/jpeg",
	"webp": "image/webp", "gif": "image/gif",
}

// ext returns name's lower-cased extension without the leading dot.
func ext(name string) string {
	return strings.ToLower(strings.TrimPrefix(filepath.Ext(name), "."))
}

// AllowedAttachment reports whether name's extension is on the allow-list.
func AllowedAttachment(name string) bool {
	return allowedExt[ext(name)]
}

// IsImage reports whether name is an inline-previewable image by its extension.
func IsImage(name string) bool {
	_, ok := imageType[ext(name)]
	return ok
}

// ContentType returns the safe content-type the console serves the attachment
// with: the matching image type for an image, else application/octet-stream so a
// non-image is downloaded rather than rendered.
func ContentType(name string) string {
	if t, ok := imageType[ext(name)]; ok {
		return t
	}
	return "application/octet-stream"
}
