
# Copyright 2017-present Open Networking Foundation
#
# 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 helpers import *
import unittest
import os
from tosca.parser import TOSCA_Parser

class TOSCA_Parser_Test(unittest.TestCase):

    def test_get_tosca_models_by_name(self):
        """
        [TOSCA_Parser] get_tosca_models_by_name: should extract models from the TOSCA recipe and store them in a dict
        """
        class FakeNode:
            def __init__(self, name):
                self.name = name

        class FakeTemplate:
            nodetemplates = [
                FakeNode('model1'),
                FakeNode('model2')
            ]


        res = TOSCA_Parser.get_tosca_models_by_name(FakeTemplate)
        self.assertIsInstance(res['model1'], FakeNode)
        self.assertIsInstance(res['model2'], FakeNode)

        self.assertEqual(res['model1'].name, 'model1')
        self.assertEqual(res['model2'].name, 'model2')

    def test_populate_dependencies(self):
        """
        [TOSCA_Parser] populate_dependencies: if a recipe has dependencies, it should find the ID of the requirements and add it to the model
        """
        class FakeRecipe:
            requirements = [
                {
                    'site': {
                        'node': 'site_onlab',
                        'relationship': 'tosca.relationship.BelongsToOne'
                    }
                }
            ]

        class FakeSite:
            id = 1
            name = 'onlab'

        class FakeModel:
            name = 'test@opencord.org'

        saved_models = {
            'site_onlab': FakeSite
        }

        model = TOSCA_Parser.populate_dependencies(FakeModel, FakeRecipe.requirements, saved_models)
        self.assertEqual(model.site_id, 1)

    def test_get_ordered_models_template(self):
        """
        [TOSCA_Parser] get_ordered_models_template: Create a list of templates based on topsorted models
        """
        ordered_models = ['foo', 'bar']

        templates = {
            'foo': 'foo_template',
            'bar': 'bar_template'
        }

        ordered_templates = TOSCA_Parser.get_ordered_models_template(ordered_models, templates)

        self.assertEqual(ordered_templates[0], 'foo_template')
        self.assertEqual(ordered_templates[1], 'bar_template')

    def test_topsort_dependencies(self):
        """
        [TOSCA_Parser] topsort_dependencies: Create a list of models based on dependencies
        """
        class FakeTemplate:
            def __init__(self, name, deps):
                self.name = name
                self.dependencies_names =  deps


        templates = {
            'deps': FakeTemplate('deps', ['main']),
            'main': FakeTemplate('main', []),
        }

        sorted = TOSCA_Parser.topsort_dependencies(templates)

        self.assertEqual(sorted[0], 'main')
        self.assertEqual(sorted[1], 'deps')

    def test_compute_dependencies(self):
        """
        [TOSCA_Parser] compute_dependencies: augment the TOSCA nodetemplate with information on requirements (aka related models)
        """

        parser = TOSCA_Parser('', 'user', 'pass')

        class FakeNode:
            def __init__(self, name, requirements):
                self.name = name
                self.requirements = requirements

        main = FakeNode('main', [])
        dep = FakeNode('dep', [{'relation': {'node': 'main'}}])

        models_by_name = {
            'main': main,
            'dep': dep
        }

        class FakeTemplate:
            nodetemplates = [dep, main]

        parser.compute_dependencies(FakeTemplate, models_by_name)

        templates = FakeTemplate.nodetemplates
        augmented_dep = templates[0]
        augmented_main = templates[1]

        self.assertIsInstance(augmented_dep.dependencies[0], FakeNode)
        self.assertEqual(augmented_dep.dependencies[0].name, 'main')
        self.assertEqual(augmented_dep.dependencies_names[0], 'main')

        self.assertEqual(len(augmented_main.dependencies), 0)
        self.assertEqual(len(augmented_main.dependencies_names), 0)

    def test_populate_model(self):
        """
        [TOSCA_Parser] populate_model: augment the GRPC model with data from TOSCA
        """
        class FakeModel:
            pass

        data = {
            'name': 'test',
            'foo': 'bar',
            'number': 1
        }

        model = TOSCA_Parser.populate_model(FakeModel, data)

        self.assertEqual(model.name, 'test')
        self.assertEqual(model.foo, 'bar')
        self.assertEqual(model.number, 1)

    def test_populate_model_error(self):
        """
        [TOSCA_Parser] populate_model: should print a meaningful error message
        """

        class FakeModel:

            model_name = "FakeModel"

            def __setattr__(self, name, value):
                if name == 'foo':
                    raise TypeError('reported exception')
                else:
                    super(FakeModel, self).__setattr__(name, value)

        data = {
            'name': 'test',
            'foo': None,
            'number': 1
        }


        model = FakeModel()

        with self.assertRaises(Exception) as e:
            model = TOSCA_Parser.populate_model(model, data)
        self.assertEqual(e.exception.message, 'Failed to set None on field foo for class FakeModel, Exception was: "reported exception"')

    def test_translate_exception(self):
        """
        [TOSCA_Parser] translate_exception: convert a TOSCA Parser exception in a user readable string
        """
        e = TOSCA_Parser._translate_exception("Non tosca exception")
        self.assertEqual(e, "Non tosca exception")

        e = TOSCA_Parser._translate_exception("""        
MissingRequiredFieldError: some message
    followed by unreadable
    and mystic
        python error
        starting at line
            38209834 of some file
UnknownFieldError: with some message
    followed by useless things
ImportError: with some message
    followed by useless things
InvalidTypeError: with some message
    followed by useless things
TypeMismatchError: with some message
    followed by useless things
        """)
        self.assertEqual(e, """MissingRequiredFieldError: some message
UnknownFieldError: with some message
ImportError: with some message
InvalidTypeError: with some message
TypeMismatchError: with some message
""")

    def test_save_recipe_to_tmp_file(self):
        """
        [TOSCA_Parser] save_recipe_to_tmp_file: should save a TOSCA recipe to a tmp file
        """
        parser = TOSCA_Parser('', 'user', 'pass')
        parser.recipe_file = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'test_tmp.yaml')

        parser.save_recipe_to_tmp_file('my tosca')

        self.assertTrue(os.path.exists(parser.recipe_file))

        content = open(parser.recipe_file).read()

        self.assertEqual(content, 'my tosca')

        os.remove(parser.recipe_file)