import unittest

from network_contract import ContractFailure, plans, verify_created
from network_prepare import prepare
from network_test_fixture import Host, config


class ConfiguredIPAMHost(Host):
    """Moby28 buildIPAMResources returns the authored gateway for explicit subnet config."""
    def command(self, argv, seconds=10):
        identity = super().command(argv, seconds=seconds)
        pool = self.networks[-1]['IPAM']['Config'][0]
        if '--gateway' in argv:
            pool['Gateway'] = argv[argv.index('--gateway') + 1]
        else:
            pool.pop('Gateway')
        return identity


class ExplicitGatewayTests(unittest.TestCase):
    def test_explicit_subnet_also_requests_the_exact_gateway_needed_for_moby28_readback(self):
        host = ConfiguredIPAMHost()
        result = prepare(config('first'), 'first', **host.arguments())
        pool = host.networks[-1]['IPAM']['Config'][0]
        self.assertEqual(pool, {'Subnet': '172.28.1.0/24', 'Gateway': '172.28.1.1'})
        self.assertEqual(result['networks'][0]['subnets'], ['172.28.1.0/24'])
        self.assertIn('--gateway', host.calls[0])
        replay = prepare(config('first'), 'first', **host.arguments())
        self.assertEqual(replay['networks'][0]['id'], result['networks'][0]['id'])
        self.assertEqual(len(host.calls), 1)

    def test_missing_different_or_augmented_ipam_is_still_refused(self):
        for change in ({'Gateway': None}, {'Gateway': '172.28.1.2'}, {'IPRange': '172.28.1.128/25'},
                       {'AuxiliaryAddresses': {'reserved': '172.28.1.10'}}, {'Unknown': ''}):
            host = ConfiguredIPAMHost()
            prepare(config('first'), 'first', **host.arguments())
            row = host.networks[-1]
            row['IPAM']['Config'][0].update(change)
            if row['IPAM']['Config'][0]['Gateway'] is None:
                row['IPAM']['Config'][0].pop('Gateway')
            with self.subTest(change=change), self.assertRaisesRegex(ContractFailure, 'created_network_unverified'):
                verify_created(plans(config('first'), 'first')[0], row, '172.28.1.0/24')


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