# -*- coding: utf-8 -*-
"""Smoke tests for jb_mail_inbox Phase 2 contact routing."""
import re

Module = env['ir.module.module'].search([('name', '=', 'jb_mail_inbox')], limit=1)
Server = env['mail.sync.server']
Message = env['mail.sync.message']
Partner = env['res.partner']
MailMessage = env['mail.message']

results = []

def check(name, ok, detail=''):
    results.append((name, ok, detail))
    status = 'PASS' if ok else 'FAIL'
    print('%s | %s | %s' % (status, name, detail))


# 1. Module installed
check(
    'Module installed',
    Module.state == 'installed',
    'state=%s version=%s' % (Module.state, Module.latest_version),
)

# 2. Mail server configured
servers = Server.search([('active', '=', True)])
check('Active IMAP server', bool(servers), 'count=%s' % len(servers))

total = Message.search_count([])
routed = Message.search_count([('is_routed', '=', True)])
unrouted = Message.search_count([('is_routed', '=', False)])
check('Inbox has messages', total > 0, 'total=%s routed=%s unrouted=%s' % (total, routed, unrouted))

# 3. Sample message has routing fields
sample = Message.search([], order='id desc', limit=1)
if sample:
    check(
        'Routing fields on message',
        'email_cc' in sample._fields and 'partner_ids' in sample._fields and 'is_routed' in sample._fields,
        'message id=%s subject=%r' % (sample.id, (sample.subject or '')[:50]),
    )

# 4. Partner with linked messages has log notes
linked_partners = Partner.search([('mail_sync_message_count', '>', 0)], limit=3)
if linked_partners:
    partner = linked_partners[0]
    note_count = MailMessage.search_count([
        ('model', '=', 'res.partner'),
        ('res_id', '=', partner.id),
        ('subject', 'ilike', '[Inbox]%'),
    ])
    check(
        'Contact has [Inbox] log notes',
        note_count > 0,
        'partner=%s (%s) notes=%s linked_msgs=%s' % (
            partner.name, partner.email, note_count, partner.mail_sync_message_count,
        ),
    )
else:
    # Create test partner from a known from-address and route
    msg = Message.search([('is_routed', '=', False)], limit=1)
    if msg:
        emails = msg._extract_participant_emails()
        check('Participant email extraction', bool(emails), 'emails=%s' % emails[:3])
    else:
        msg = Message.search([], limit=1)
    if msg:
        addrs = msg._extract_participant_emails()
        if addrs:
            test_email = addrs[0]
            partner = Partner.search([('email', '=ilike', test_email)], limit=1)
            if not partner:
                partner = Partner.create({'name': 'Test %s' % test_email, 'email': test_email})
            before = MailMessage.search_count([
                ('model', '=', 'res.partner'),
                ('res_id', '=', partner.id),
                ('subject', 'ilike', '[Inbox]%'),
            ])
            msg._route_to_contacts()
            after = MailMessage.search_count([
                ('model', '=', 'res.partner'),
                ('res_id', '=', partner.id),
                ('subject', 'ilike', '[Inbox]%'),
            ])
            check(
                'Route creates log note',
                after > before,
                'partner=%s before=%s after=%s' % (test_email, before, after),
            )

# 5. Idempotency — second route must not add notes
if linked_partners:
    partner = linked_partners[0]
    before = MailMessage.search_count([
        ('model', '=', 'res.partner'),
        ('res_id', '=', partner.id),
        ('subject', 'ilike', '[Inbox]%'),
    ])
    msgs = Message.search([('partner_ids', 'in', partner.id)])
    msgs._route_to_contacts()
    after = MailMessage.search_count([
        ('model', '=', 'res.partner'),
        ('res_id', '=', partner.id),
        ('subject', 'ilike', '[Inbox]%'),
    ])
    check('Idempotency (no duplicate notes)', before == after, 'notes=%s' % after)

# 6. Mailbox user excluded from matching
if servers:
    server = servers[0]
    mailbox = (server.user or '').lower()
    fake = Message.new({
        'server_id': server.id,
        'email_from': mailbox,
        'email_to': mailbox,
        'email_cc': mailbox,
    })
    emails = fake._extract_participant_emails()
    check(
        'Mailbox address excluded',
        mailbox not in emails,
        'mailbox=%s extracted=%s' % (mailbox, emails),
    )

# 7. Log note body contains metadata
routed_msg = Message.search([('is_routed', '=', True), ('partner_ids', '!=', False)], limit=1)
if routed_msg:
    body = routed_msg._build_log_note_body()
    check(
        'Log note body has metadata',
        all(x in body for x in ('From:', 'To:', 'Subject:', 'Mail Inbox #')),
        'msg id=%s' % routed_msg.id,
    )
    if routed_msg.attachment_ids:
        att_ids = routed_msg._copy_attachments_for_post()
        check('Attachment copy for post', len(att_ids) == len(routed_msg.attachment_ids), 'copies=%s' % len(att_ids))

# 8. Cron job active
cron = env['ir.cron'].search([('name', 'ilike', 'JB Mail Inbox')], limit=1)
check('Fetch cron active', cron and cron.active, cron.name if cron else 'missing')

# 9. IMAP connection (optional)
if servers:
    server = servers[0]
    try:
        conn = server._connect_imap()
        conn.select(server.folder, readonly=True)
        conn.logout()
        check('IMAP connection', True, 'server=%s' % server.name)
    except Exception as exc:
        check('IMAP connection', False, str(exc)[:120])

passed = sum(1 for _n, ok, _d in results if ok)
failed = sum(1 for _n, ok, _d in results if not ok)
print('---')
print('SUMMARY: %s passed, %s failed, %s total' % (passed, failed, len(results)))
env.cr.commit()
