package imap

import (
	"strings"
	"testing"
)

func TestDecodeBareBase64IfNeeded_samsungMessage(t *testing.T) {
	const encoded = "U0FNU1VORwpSw6lzZXJ2w6kgYXV4IHByb2Zlc3Npb25uZWxzCgrigIoKVm9zIMOpcXVpcGVzIG9u\r\n" +
		"dCBiZXNvaW4KZGUgc29sdXRpb25zIG1vYmlsZXMKZXQgcm9idXN0ZXMuCgpTYW1zdW5nIFBybyBy\r\n" +
		"w6lwb25kIGF1eCBtw6l0aWVycyBkZSBsYSBjb25zdHJ1"

	decoded := decodeBareBase64IfNeeded(encoded)
	if decoded == encoded {
		t.Fatal("expected base64 decode")
	}
	if !strings.HasPrefix(decoded, "SAMSUNG") {
		t.Fatalf("decoded = %q", decoded)
	}
	if !strings.Contains(decoded, "professionnels") {
		t.Fatalf("decoded = %q, want utf-8 text", decoded)
	}
}

func TestDecodeBareQuotedPrintableIfNeeded_frenchMarketing(t *testing.T) {
	const qp = "Hello = Eliott,\n\nNous pouvons faire appara=C3=AEtre votre marque en premi=C3=A8re =\n" +
		" position dans les Google Suggests"

	decoded := decodeBareQuotedPrintableIfNeeded(qp)
	if decoded == qp {
		t.Fatal("expected quoted-printable decode")
	}
	if !strings.Contains(decoded, "apparaître") {
		t.Fatalf("decoded = %q, want apparaître", decoded)
	}
	if strings.Contains(decoded, "=C3=") {
		t.Fatalf("still contains qp escapes: %q", decoded)
	}
}

func TestRepairStoredBodies_quotedPrintableHTML(t *testing.T) {
	const qpHTML = `<html><body><div style=3D"color: rgb(65, 65, 65);">appara=C3=AEtre</div></body></html>`
	_, html := RepairStoredBodies("", qpHTML)
	if !strings.Contains(html, "apparaître") {
		t.Fatalf("html = %q", html)
	}
	if strings.Contains(html, "=3D") {
		t.Fatal("html still quoted-printable encoded")
	}
}

func TestRepairSnippet_truncatedBase64Preview(t *testing.T) {
	snippet := truncate(
		"U0FNU1VORwpSw6lzZXJ2w6kgYXV4IHByb2Zlc3Npb25uZWxzCgrigIoKVm9zIMOpcXVpcGVzIG9u"+
			"dCBiZXNvaW4KZGUgc29sdXRpb25zIG1vYmlsZXMKZXQgcm9idXN0ZXMuCgpTYW1zdW5nIFBybyBy"+
			"w6lwb25kIGF1eCBtw6l0aWVycyBkZSBsYSBjb25zdHJ1Y3Rpb24uCgrigIoKPiBEw6ljb3V2cmly",
		200,
	)
	repaired := RepairSnippet(snippet)
	if !strings.HasPrefix(repaired, "SAMSUNG") {
		t.Fatalf("snippet = %q, want decoded preview", repaired)
	}
}

func TestRepairStoredBodies_base64HTML(t *testing.T) {
	const encodedHTML = "PCFET0NUWVBFIGh0bWwgUFVCTElDICItLy9XM0MvL0RURCBYSFRNTCAxLjAgVHJhbnNpdGlvbmFs"
	_, html := RepairStoredBodies("", encodedHTML)
	if !strings.HasPrefix(html, "<!DOCTYPE") && !strings.HasPrefix(html, "<!doctype") {
		t.Fatalf("html = %q, want decoded doctype", html)
	}
}

func TestRepairStoredBodies_rawMIMEInDB(t *testing.T) {
	raw := string(buildMultipartMessage(t, "alternative", []mimePart{
		{
			contentType: "text/plain; charset=utf-8",
			body:        []byte("Stored fix"),
			transferEnc: "base64",
		},
	}))

	repairedText, repairedHTML := RepairStoredBodies(raw, "")
	if repairedText != "Stored fix" {
		t.Fatalf("repaired text = %q, want Stored fix", repairedText)
	}
	if repairedHTML != "" {
		t.Fatalf("repaired html = %q, want empty", repairedHTML)
	}
}

func TestRepairSubject_brokenSymbolUsesBodyFallback(t *testing.T) {
	qpHTML := `<html><body><p>Hello Eliott, Nous pouvons faire apparaître votre marque.</p></body></html>`
	subject := RepairSubject("▱", "", qpHTML, nil)
	if subjectLooksBroken(subject) {
		t.Fatalf("subject = %q, want readable fallback", subject)
	}
	if !strings.Contains(subject, "Hello") {
		t.Fatalf("subject = %q", subject)
	}
}
