#!/usr/bin/python2
#
# Copyright 2019 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

import json
import os
import tempfile
import unittest

import common

from autotest_lib.client.common_lib import error
from autotest_lib.server.cros.faft.utils import config


class CanLoadDefaultTestCase(unittest.TestCase):
    """Ensure that configs can load the default JSON"""

    def runTest(self):
        """Main test logic"""
        platform = "foo"
        cfg = config.Config(platform)
        self.assertIsInstance(cfg.has_keyboard, bool)


class _MockConfigTestCaseBaseClass(unittest.TestCase):
    """
    Base class which handles the setup/teardown of mock config files.

    Sub-classes should declare a class attribute, mock_configs,
    as a dict representing all platforms to be written as JSON files.
    This class writes those JSON files during setUp() and deletes them
    during tearDown().
    During runTest(), sub-classes can create config.Config instances by name
    and run assertions as normal.

    """

    mock_configs = None

    def setUp(self):
        """Set up a tempfile containing the test data"""
        if self.mock_configs is None:
            return

        # Setup mock config._CONFIG_DIR, but remember the original.
        self.mock_config_dir = tempfile.mkdtemp()
        self.original_config_dir = config._CONFIG_DIR
        config._CONFIG_DIR = self.mock_config_dir

        # Write mock config file.
        with open(config._consolidated_json_fp(), 'w') as f:
            json.dump(self.mock_configs, f)

    def tearDown(self):
        """After tests are complete, delete the tempfile"""
        if self.mock_configs is None:
            return
        os.remove(config._consolidated_json_fp())
        os.rmdir(self.mock_config_dir)
        config._CONFIG_DIR = self.original_config_dir


class InheritanceTestCase(_MockConfigTestCaseBaseClass):
    """Ensure that platforms inherit attributes correctly"""

    mock_configs = {
            'DEFAULTS': {
                    'no_override': 'default',
                    'parent_override': 'default',
                    'child_override': 'default',
                    'both_override': 'default',
                    'parent': None
            },
            'childboard': {
                    'child_override': 'child',
                    'both_override': 'child',
                    'parent': 'parentboard'
            },
            'parentboard': {
                    'parent_override': 'parent',
                    'both_override': 'parent'
            }
    }

    def runTest(self):
        """
        Verify that the following situations resolve correctly:
            A platform that inherit some overridess from another platform
            A platform that does not inherit from another platform
            A platform not found in the config file
        """
        child_config = config.Config('childboard')
        #print(child_config)
        self.assertEqual(child_config.no_override, 'default')
        self.assertEqual(child_config.parent_override, 'parent')
        self.assertEqual(child_config.child_override, 'child')
        self.assertEqual(child_config.both_override, 'child')
        with self.assertRaises(AttributeError):
            child_config.foo  # pylint: disable=pointless-statement

        parent_config = config.Config('parentboard')
        self.assertEqual(parent_config.no_override, 'default')
        self.assertEqual(parent_config.parent_override, 'parent')
        self.assertEqual(parent_config.child_override, 'default')
        self.assertEqual(parent_config.both_override, 'parent')

        foo_config = config.Config('foo')
        self.assertEqual(foo_config.no_override, 'default')
        self.assertEqual(foo_config.parent_override, 'default')
        self.assertEqual(foo_config.child_override, 'default')
        self.assertEqual(foo_config.both_override, 'default')

        # While we're here, verify that str(config) doesn't break
        str(child_config)  # pylint: disable=pointless-statement


class ModelOverrideTestCase(_MockConfigTestCaseBaseClass):
    """Verify that models of boards inherit overrides with proper precedence"""
    mock_configs = {
            'parentboard': {
                    'attr1': 'parent_attr1',
                    'attr2': 'parent_attr2',
                    'models': {
                            'modelA': {
                                    'attr1': 'parent_modelA_attr1'
                            }
                    }
            },
            'childboard': {
                    'parent': 'parentboard',
                    'attr1': 'child_attr1',
                    'models': {
                            'modelA': {
                                    'attr1': 'child_modelA_attr1'
                            }
                    }
            },
            'DEFAULTS': {
                    'models': None,
                    'attr1': 'default',
                    'attr2': 'default'
            }
    }

    def runTest(self):
        """Run assertions on test data"""
        child_config = config.Config('childboard')
        child_modelA_config = config.Config('childboard', 'modelA')
        child_modelB_config = config.Config('childboard', 'modelB')
        parent_config = config.Config('parentboard')
        parent_modelA_config = config.Config('parentboard', 'modelA')
        parent_modelB_config = config.Config('parentboard', 'modelB')

        self.assertEqual(child_config.attr1, 'child_attr1')
        self.assertEqual(child_config.attr2, 'parent_attr2')
        self.assertEqual(child_modelA_config.attr1, 'child_modelA_attr1')
        self.assertEqual(child_modelA_config.attr2, 'parent_attr2')
        self.assertEqual(child_modelB_config.attr1, 'child_attr1')
        self.assertEqual(child_modelB_config.attr2, 'parent_attr2')
        self.assertEqual(parent_config.attr1, 'parent_attr1')
        self.assertEqual(parent_config.attr2, 'parent_attr2')
        self.assertEqual(parent_modelA_config.attr1, 'parent_modelA_attr1')
        self.assertEqual(parent_modelA_config.attr2, 'parent_attr2')
        self.assertEqual(parent_modelB_config.attr1, 'parent_attr1')
        self.assertEqual(parent_modelB_config.attr2, 'parent_attr2')


class DirectSelfInheritanceTestCase(_MockConfigTestCaseBaseClass):
    """Ensure that a config which inherits from itself raises an error."""

    mock_configs = {
        'selfloop': {
            'parent': 'selfloop',
        },
    }

    def runTest(self):
        """Run assertions on test data."""
        with self.assertRaises(error.TestError):
            config.Config('selfloop')


class IndirectSelfInheritanceTestCase(_MockConfigTestCaseBaseClass):
    """Ensure that configs which inherit from each other raise an error."""

    mock_configs = {
        'indirectloop1': {
            'parent': 'indirectloop2',
        },
        'indirectloop2': {
            'parent': 'indirectloop1',
        },
        'indirectloop3': {
            'parent': 'indirectloop1',
        },
    }

    def runTest(self):
        """Run assertions on test data."""
        with self.assertRaises(error.TestError):
            config.Config('indirectloop1')
        with self.assertRaises(error.TestError):
            config.Config('indirectloop3')


class FindMostSpecificConfigTestCase(_MockConfigTestCaseBaseClass):
    """Ensure that configs named like $BOARD-kernelnext load $BOARD.json."""

    mock_configs = {
            'DEFAULTS': {},
            'samus': {},
            'veyron': {},
            'minnie': {'parent': 'veyron'},
    }

    def runTest(self):
        cfg = config.Config('samus-kernelnext')
        self.assertEqual(config.Config('samus-kernelnext').platform, 'samus')
        self.assertEqual(config.Config('samus-arc-r').platform, 'samus')
        self.assertEqual(config.Config('veyron_minnie').platform, 'minnie')
        self.assertEqual(config.Config('veyron_monroe').platform, 'veyron')
        self.assertEqual(config.Config('veyron_minnie-arc-r').platform, 'minnie')
        self.assertEqual(config.Config('veyron_monroe-arc-r').platform, 'veyron')


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