#
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License.  You may obtain a copy of the License at
#
#   http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied.  See the License for the
# specific language governing permissions and limitations
# under the License.
#

from __future__ import unicode_literals
from __future__ import division
from __future__ import absolute_import
from __future__ import print_function

from system_test import TestCase, Qdrouterd


class RouterTestDeprecatedLinkRoute(TestCase):

    @classmethod
    def setUpClass(cls):
        """

        :return:
        """
        super(RouterTestDeprecatedLinkRoute, cls).setUpClass()

        name = "test-router"

        config = Qdrouterd.Config([
            ('router', {'mode': 'standalone', 'id': 'QDR.A'}),
            # We are trying to declare a link route with both 'dir' and 'direction' attributes.
            # The router must not start in this case.
            ('linkRoute', {'prefix': 'org.apache', 'containerId': 'QDR.A', 'direction': 'in', 'dir': 'in'}),
            ('linkRoute', {'prefix': 'org.apache', 'containerId': 'QDR.A', 'direction': 'out'}),
            ('listener', {'port': cls.tester.get_port(), 'maxFrameSize': '2048', 'stripAnnotations': 'in'}),
        ])

        cls.router = cls.tester.qdrouterd(name, config, wait=False, perform_teardown=False)

        # Try connecting for 4 seconds. If unable to connect, just move on.
        try:
            cls.router.wait_ready(timeout=4)
        except:
            pass

    def test_deprecated_link_route(self):
        with open('../setUpClass/test-router-2.out', 'r') as router_log:
            log_lines = router_log.read().split("\n")
            search_lines = [s for s in log_lines if "org.apache.qpid.dispatch.router.config.linkRoute: Both 'dir' and 'direction' cannot be specified for entity 'linkRoute'" in s]
            self.assertTrue(len(search_lines) > 0)


class RouterTestDeprecatedLAutoLink(TestCase):

    @classmethod
    def setUpClass(cls):
        super(RouterTestDeprecatedLAutoLink, cls).setUpClass()

        name = "test-autolink"


        config = Qdrouterd.Config([
            ('router', {'mode': 'standalone', 'id': 'QDR.B'}),
            # We are trying to declare a link route with both 'dir' and 'direction' attributes.
            # The router must not start in this case.
            ('autoLink', {'externalAddr': 'node.100', 'addr': 'node.10',
                          'containerId': 'container.1',
                          'direction': 'out'}),
            ('autoLink', {'addr': 'node.1', 'containerId': 'container.1', 'dir': 'in',  'direction': 'in'}),
            ('autoLink', {'addr': 'node.1', 'containerId': 'container.1', 'direction': 'out'}),

            ('listener', {'port': cls.tester.get_port()}),
        ])
        cls.router = cls.tester.qdrouterd(name, config, wait=False, perform_teardown=False)

        # Try connecting for 4 seconds. If unable to connect, just move on.
        try:
            cls.router.wait_ready(timeout=4)
        except:
            pass

    def test_deprecated_auto_link(self):
        with open('../setUpClass/test-autolink-1.out', 'r') as router_log:
            log_lines = router_log.read().split("\n")
            search_lines = [s for s in log_lines if
                            "org.apache.qpid.dispatch.router.config.autoLink: Both 'dir' and 'direction' cannot be specified for entity 'autoLink'" in s]
            self.assertTrue(len(search_lines) > 0)

            external_addr_search_lines = [s for s in log_lines if
                            "Attribute 'externalAddr' of entity 'autoLink' has been deprecated. Use 'externalAddress' instead" in s]
            self.assertTrue(len(external_addr_search_lines) > 0)







