package imap

import (
	"context"
	"encoding/base64"
	"strings"
	"testing"

	"github.com/ultisuite/ulti-backend/internal/mail/credentials"
)

func TestResolveCredential_missing(t *testing.T) {
	w := &SyncWorker{credentials: &credentials.Manager{}}

	_, err := w.resolveCredential(context.Background(), "acc-1", nil)
	if err == nil || err.Error() != "missing credentials" {
		t.Fatalf("resolveCredential(nil) error = %v, want missing credentials", err)
	}

	_, err = w.resolveCredential(context.Background(), "acc-1", []byte{})
	if err == nil || err.Error() != "missing credentials" {
		t.Fatalf("resolveCredential([]) error = %v, want missing credentials", err)
	}
}

func TestResolveCredential_plaintextForbidden(t *testing.T) {
	w := &SyncWorker{credentials: &credentials.Manager{}}

	_, err := w.resolveCredential(context.Background(), "acc-1", []byte(`{"username":"alice","password":"secret"}`))
	if err == nil || err.Error() != "plaintext credentials forbidden" {
		t.Fatalf("resolveCredential(plaintext) error = %v, want plaintext credentials forbidden", err)
	}
}

func TestResolveCredential_missingManager(t *testing.T) {
	key := base64.StdEncoding.EncodeToString([]byte("0123456789abcdef0123456789abcdef"))
	manager, err := credentials.NewManager("v1:"+key, "v1")
	if err != nil {
		t.Fatalf("new manager: %v", err)
	}
	blob, err := manager.Encrypt("alice@example.com", "secret")
	if err != nil {
		t.Fatalf("encrypt: %v", err)
	}

	w := &SyncWorker{credentials: nil}
	_, err = w.resolveCredential(context.Background(), "acc-1", blob)
	if err == nil || err.Error() != "credential manager not configured" {
		t.Fatalf("resolveCredential(no manager) error = %v, want credential manager not configured", err)
	}
}

func TestResolveCredential_encryptedSuccess(t *testing.T) {
	key := base64.StdEncoding.EncodeToString([]byte("0123456789abcdef0123456789abcdef"))
	manager, err := credentials.NewManager("v1:"+key, "v1")
	if err != nil {
		t.Fatalf("new manager: %v", err)
	}
	blob, err := manager.Encrypt("alice@example.com", "secret")
	if err != nil {
		t.Fatalf("encrypt: %v", err)
	}

	w := &SyncWorker{credentials: manager}
	cred, err := w.resolveCredential(context.Background(), "acc-1", blob)
	if err != nil {
		t.Fatalf("resolveCredential(encrypted) error = %v", err)
	}
	if cred.Username != "alice@example.com" || cred.Password != "secret" {
		t.Fatalf("got %+v, want alice@example.com/secret", cred)
	}
}

func TestResolveCredential_decryptFailure(t *testing.T) {
	key := base64.StdEncoding.EncodeToString([]byte("0123456789abcdef0123456789abcdef"))
	manager, err := credentials.NewManager("v1:"+key, "v1")
	if err != nil {
		t.Fatalf("new manager: %v", err)
	}

	w := &SyncWorker{credentials: manager}
	_, err = w.resolveCredential(context.Background(), "acc-1", []byte("UMC1|v1|invalid|payload"))
	if err == nil {
		t.Fatal("expected decrypt error")
	}
	if !strings.Contains(err.Error(), "decode nonce") {
		t.Fatalf("unexpected error: %v", err)
	}
}
