#!/usr/bin/env python3
"""Unit tests."""

import unittest

from bind9_records import Record, TextData
from bind9_records.tokenizer import Scanner, Tokenizer

class TestAddress(unittest.TestCase):
    """Test address records."""

    maxDiff = None

    def test_tokenizer(self) -> None:
        tests = [
            'h3,h2',
        ]
        for test in tests:
            scanner = Scanner(test)
            output = ''
            while (scanner):
                output += scanner.next()
            self.assertEqual(test, output)

            tokens = Tokenizer(test)
            output = ''
            while (tokens):
                output += tokens.next()
            self.assertEqual(test, output)

    def test_a_record_parse(self) -> None:
        tests = [
            'test\tA\t127.0.0.1',
            'test\tAAAA\t::1',
        ]

        for test in tests:
            r = Record(test)
            self.assertEqual(test, str(r))

    def test_caa_record_parse(self) -> None:
        tests = [
            'test\tCAA\t0 issue ";"',
            'test\tCAA\t1 issue example.com.',
            'test\tCAA\t1 issue "example.com; validationmethods=dns-01,http-01"',
            'test\tCAA\t1 iodef admin@example.com',
        ]

        for test in tests:
            r = Record(test)
            self.assertEqual(test, str(r))

    def test_cert_record_parse(self) -> None:
        tests = [
            'test\tCERT\tPGP 0 0 MTIzNDU2',
            'test\tCERT\t37 0 42 MTIzNDU2',
        ]

        for test in tests:
            r = Record(test)
            self.assertEqual(test, str(r))

    def test_cname_record_parse(self) -> None:
        tests = [
            'test\tCNAME\texample.com.',
            'test\tCNAME\texample\\.dot.bar.',
        ]

        for test in tests:
            r = Record(test)
            self.assertEqual(test, str(r))

    def test_ds_record_parse(self) -> None:
        tests = [
            'test\tDS\t123 1 2 0123456789ABCDEF',
            # 'test\tDS\t123 ECDSAP256SHA256 SHA256 0123456789ABCDEF',
        ]

        for test in tests:
            r = Record(test)
            self.assertEqual(test, str(r))

    def test_loc_record_parse(self) -> None:
        tests = [
            'test\tLOC\t42 21 28.764 N 71 0 51.617 W -44.4m 2000.1m',
            'test\tLOC\t42 S 71 E 44m',
        ]

        for test in tests:
            r = Record(test)
            self.assertEqual(test, str(r))

    def test_mx_record_parse(self) -> None:
        tests = [
            'test\tMX\t0 example.com.',
            'test\tMX\t0 example\\.dot.bar.',
            'test\tMX\t100 .',
        ]

        for test in tests:
            r = Record(test)
            self.assertEqual(test, str(r))

    def test_naptr_record_parse(self) -> None:
        tests = [
            'test\tNAPTR\t100 50 "a" "z3950+N2L+N2C" "" cidserver.example.com.',
            ('test\tNAPTR\t' r'100 10 "" "" "!^urn:cid:.+@([^\.]+\.)(.*)$!\2!i" .'),
        ]

        for test in tests:
            r = Record(test)
            self.assertEqual(test, str(r))

    def test_srv_record_parse(self) -> None:
        tests = [
            'test\tSRV\t0 0 443 example.com.',
            'test\tSRV\t0 0 8443 example\\.dot.bar.',
        ]

        for test in tests:
            r = Record(test)
            self.assertEqual(test, str(r))

    def test_svcb_record_parse(self) -> None:
        tests = [
            'test\tSVCB\t1 . alpn=h3,h2 ipv4hint=45.33.33.164 ipv6hint=2600:3c01:e000:131::2:0',
            ('test\tSVCB\t' r'1 . alpn=h3,h2\,hx ipv4hint=45.33.33.164 ipv6hint=2600:3c01:e000:131::2:0'),
        ]

        for test in tests:
            r = Record(test)
            self.assertEqual(test, str(r))

    def test_tlsa_record_parse(self) -> None:
        tests = [
            'test\tTLSA\t0 0 0 0123456789ABCDEF',
            'test\tTLSA\t0 0 1 0123456789ABCDEF',
            'test\tTLSA\t0 0 2 0123456789ABCDEF',
            'test\tTLSA\t(\n\t\t0 0 2 0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789\n\t\tABCDEF0123456789ABCDEF0123456789ABCDEF\n\t)',
        ]

        for test in tests:
            r = Record(test)
            self.assertEqual(test, str(r))

    def test_txt_record_parse(self) -> None:
        tests = [
            ('test\tTXT\t' r'"just some \" text"'),
            'test\tTXT\t"v=spf1 include:example.com."',
            ('test\tTXT\t' r'"v=DMARC1; adkim=s; aspf=r; ruf=mailto:test@example.com;"'),
            ('test\tTXT\t' r'"v=DMARC1; ruf=mailto:test1@exam\,ple.com,mailto:test2@exam\"p\;le.com;"'),
            ('test\tTXT\t' r'"v=TLSRPTv1; rua=mailto:test@example.com;"'),
            ('test\tTXT\t' r'"v=STSv1; id=20241106203027Z;"'),
        ]

        for test in tests:
            r = Record(test)
            self.assertEqual(test, str(r))

    def test_txt_data_create(self) -> None:
        tests = [
            ({'data': r'some "quoted  \"  spaced"  value'},
             r'"some quoted  \"  spaced value"'),
            ({'value': 'some "quoted"  value'},
             r'"some \"quoted\"  value"'),
            ({'version': 'spf', 'mechanisms': 'include:example.com.'},
             '"v=spf1 include:example.com."'),
            ({'version': 'spf', 'mechanisms': ['a:smtp.example.com', '-all']},
             '"v=spf1 a:smtp.example.com -all"'),
            ({'version': 'dmarc', 'policy': 'reject', 'percent': 100, 'report_url_aggregate': r'mailto:test@exam\,ple.com,mailto:test2@exam"ple.com'},
             r'"v=DMARC1; p=reject; rua=mailto:test@exam\,ple.com,mailto:test2@exam\"ple.com; pct=100;"'),
            ({'version': 'sts', 'id': '0123456789'},
             '"v=STSv1; id=0123456789;"'),
            ({'version': 'tlsrpt', 'report_url_aggregate': 'mailto:test1@example.com,mailto:test2@example.com', 'this_is_not_real': 'bad data'},
             '"v=TLSRPTv1; rua=mailto:test1@example.com,mailto:test2@example.com;"'),
        ]

        for kwargs, expected in tests:
            d = TextData.create(**kwargs)
            self.assertEqual(expected, str(d))


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