# Copyright 2019 Extreme Networks, Inc.
#
# Licensed 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 orquesta.expressions import base as expr_base
from orquesta.tests.unit import base as test_base


class YAQLFacadeVariableExtractionTest(test_base.ExpressionFacadeEvaluatorTest):

    def test_empty_extraction(self):
        expr = (
            '<% just_text and $not_a_var and notctx().bar and '
            'ctx(). and ctx().() and ctx().-foobar and ctx().foobar() %>'
        )

        self.assertListEqual([], expr_base.extract_vars(expr))

    def test_single_var_extraction(self):
        expr = '<% ctx().foobar %>'

        expected_vars = [('yaql', expr, 'foobar')]

        self.assertListEqual(expected_vars, expr_base.extract_vars(expr))

    def test_single_dotted_var_extraction(self):
        expr = '<% ctx().foo.bar %>'

        expected_vars = [('yaql', expr, 'foo')]

        self.assertListEqual(expected_vars, expr_base.extract_vars(expr))

    def test_single_indexing_var_extraction(self):
        expr = '<% ctx().foo[0] %>'

        expected_vars = [('yaql', expr, 'foo')]

        self.assertListEqual(expected_vars, expr_base.extract_vars(expr))

    def test_single_functional_var_extraction(self):
        expr = '<% ctx().foo.get(bar) %>'

        expected_vars = [('yaql', expr, 'foo')]

        self.assertListEqual(expected_vars, expr_base.extract_vars(expr))

    def test_multiple_vars_extraction(self):
        expr = '<%ctx().fubar ctx().foobar ctx().foo.get(bar) ctx().fu.bar ctx().foobaz.bar[0] %>'

        expected_vars = [
            ('yaql', expr, 'foo'),
            ('yaql', expr, 'foobar'),
            ('yaql', expr, 'foobaz'),
            ('yaql', expr, 'fu'),
            ('yaql', expr, 'fubar')
        ]

        self.assertListEqual(expected_vars, expr_base.extract_vars(expr))

    def test_multiple_interleaved_vars_extraction(self):
        expr = '<% Why the ctx().foobar are you so ctx().fu.bar serious? %>'

        expected_vars = [
            ('yaql', expr, 'foobar'),
            ('yaql', expr, 'fu')
        ]

        self.assertListEqual(expected_vars, expr_base.extract_vars(expr))

    def test_vars_extraction_from_list(self):
        expr = [
            '<% abc %>',
            '<% Why the ctx().foobar are you so ctx().fu.bar serious? %>',
            'All your test_base are belong to us.',
            {'<% ctx().x %>': 123, 'k2': '<% ctx().y %>', 'k3': ['<% ctx().z %>']}
        ]

        expected_vars = [
            ('yaql', expr[1], 'foobar'),
            ('yaql', expr[1], 'fu'),
            ('yaql', '<% ctx().x %>', 'x'),
            ('yaql', '<% ctx().y %>', 'y'),
            ('yaql', '<% ctx().z %>', 'z')
        ]

        self.assertListEqual(expected_vars, expr_base.extract_vars(expr))

    def test_vars_extraction_from_dict(self):
        expr = {
            'k1': '<% abc %>',
            'k2': '<% Why the ctx().foobar are you so ctx().fu.bar serious? %>',
            'k3': ['<% ctx().z %>'],
            'k4': {'k5': '<% ctx().y %>'},
            '<% ctx().x %>': 123
        }

        expected_vars = [
            ('yaql', expr['k2'], 'foobar'),
            ('yaql', expr['k2'], 'fu'),
            ('yaql', '<% ctx().x %>', 'x'),
            ('yaql', '<% ctx().y %>', 'y'),
            ('yaql', '<% ctx().z %>', 'z')
        ]

        self.assertListEqual(expected_vars, expr_base.extract_vars(expr))
