import unittest
from lxml import etree as E

from imm0008_pdf_state import apply_state, normalize_fields

P = 'form1.Page1.'


class Imm0008StateTest(unittest.TestCase):
    def test_manual_values_clear_without_removing_captions_or_formats(self):
        raw = b'<template><subform name="form1"><field name="TextField2"><caption><value><text>Signature of Applicant</text></value></caption><value><text>Old signature</text></value></field><field name="C1CertificateIssueDate"><caption><value><text>Date: YYYY-MM-DD</text></value></caption><value><date>2020-01-01</date></value><format><picture>YYYY-MM-DD</picture></format></field></subform></template>'
        root = E.fromstring(apply_state(raw, {}, 0))
        self.assertEqual(root.xpath('//*[@name="TextField2"]/caption/value/text/text()'), ['Signature of Applicant'])
        self.assertEqual(root.xpath('//*[@name="C1CertificateIssueDate"]/caption/value/text/text()'), ['Date: YYYY-MM-DD'])
        self.assertEqual(root.xpath('//*[@name="C1CertificateIssueDate"]/format/picture/text()'), ['YYYY-MM-DD'])
        self.assertEqual(root.xpath('//field/value'), [])

    def test_north_american_district_values_clear_without_mutating_input(self):
        for country in ('511', '461', '241'):
            for base in ('q1.AddressRow2.', 'q2.ResidentialAddressRow2.'):
                prefix = P + 'contactInformation.' + base
                fields = {prefix + 'Country.Country': country, prefix + 'District': 'District value'}
                result = normalize_fields(fields)
                self.assertEqual(result[prefix + 'District'], '' if country in ('511', '461') else 'District value')
                self.assertEqual(fields[prefix + 'District'], 'District value')

    def test_selected_only_canada_phone_branch_is_visible_without_changing_script(self):
        raw = b'<template><subform name="form1"><subform name="Page1"><subform name="contactInformation"><subform name="q3-4"><subform name="Phone"><subform name="NANumber" presence="invisible"/><subform name="IntlNumber" presence="visible"/><field name="NumberCountry"><validate nullTest="error"/><event><script>keep(&quot;x&quot;);</script></event></field></subform></subform></subform></subform></subform></template>'
        result = apply_state(raw, {P+'contactInformation.q3-4.Phone.CanadaUS': '1'}, 0)
        root = E.fromstring(result)
        self.assertEqual(root.xpath('//*[@name="NANumber"]/@presence'), ['visible'])
        self.assertEqual(root.xpath('//*[@name="IntlNumber"]/@presence'), ['invisible'])
        self.assertEqual(root.xpath('//*[@name="NumberCountry"]/@access'), ['readOnly'])
        self.assertIn(b'<script>keep(&quot;x&quot;);</script>', result)

    def test_same_as_mailing_clears_only_residential_fields(self):
        fields = {P+'contactInformation.q2.SameAsMailingIndicator': 'Y', P+'contactInformation.q2.ResidentialAddressRow2.Country.Country': '511', P+'contactInformation.q1.AddressRow2.Country.Country': '511'}
        result = normalize_fields(fields)
        self.assertEqual(result[P+'contactInformation.q2.ResidentialAddressRow2.Country.Country'], '')
        self.assertEqual(result[P+'contactInformation.q1.AddressRow2.Country.Country'], '511')
        self.assertEqual(fields[P+'contactInformation.q2.ResidentialAddressRow2.Country.Country'], '511')

    def test_dependent_sections_show_exact_count_without_modifying_official_occurrence_limit(self):
        raw = b'<template><subform name="form1"><subform name="Page1"><subform name="depInfoHeader"/><subform name="depPrime"/><subform name="depHeader"/><subform name="dependants"><occur min="0" max="4"/></subform></subform></subform></template>'
        for count in [0, 1, 2, 5]:
            root = E.fromstring(apply_state(raw, {}, count))
            self.assertEqual(root.xpath('//*[@name="depPrime"]/@presence'), ['visible' if count else 'hidden'])
            self.assertEqual(root.xpath('//*[@name="dependants"]/@presence'), ['visible' if count > 1 else 'hidden'])
            self.assertEqual(root.xpath('//occur/@max'), ['4'])

    def test_csq_and_signature_state_preserve_explicit_consents(self):
        raw = b'<template><subform name="form1"><subform name="Page1"><subform name="genDetails"><subform name="q7"><field name="CSQNum"/><field name="CSQDate"/></subform></subform><subform name="declaration"><subform name="Consent1"><field name="TextField2"><value><text>Old Signature</text></value></field><field name="C1CertificateIssueDate"><value><date>2020-01-01</date></value></field><exclGroup name="FutureContact"><value><text>Y</text></value></exclGroup></subform></subform></subform></subform></template>'
        fields = {P+'genDetails.q1.Program': '02', P+'genDetails.q6.Prov': '05', P+'genDetails.q7.CSQInd': 'Y'}
        result = apply_state(raw, fields, 0)
        root = E.fromstring(result)
        self.assertEqual(root.xpath('//*[@name="CSQNum"]/@access'), ['open'])
        self.assertEqual(root.xpath('//*[@name="CSQDate"]/@access'), ['readOnly'])
        self.assertNotIn(b'Old Signature', result)
        self.assertNotIn(b'2020-01-01', result)
        self.assertEqual(root.xpath('//*[@name="FutureContact"]/value/text/text()'), ['Y'])


if __name__ == '__main__':
    unittest.main()
