#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# 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.

"""unittest for settings."""

from __future__ import print_function

import unittest
import unittest.mock as mock

import settings
import settings_factory

from field import IntegerField
from field import ListField
import download_images

from cros_utils import logger


class TestSettings(unittest.TestCase):
  """setting test class."""

  def setUp(self):
    self.settings = settings.Settings('global_name', 'global')

  def test_init(self):
    self.assertEqual(self.settings.name, 'global_name')
    self.assertEqual(self.settings.settings_type, 'global')
    self.assertIsNone(self.settings.parent)

  def test_set_parent_settings(self):
    self.assertIsNone(self.settings.parent)
    settings_parent = {'fake_parent_entry': 0}
    self.settings.SetParentSettings(settings_parent)
    self.assertIsNotNone(self.settings.parent)
    self.assertTrue(isinstance(self.settings.parent, dict))
    self.assertEqual(self.settings.parent, settings_parent)

  def test_add_field(self):
    self.assertEqual(self.settings.fields, {})
    self.settings.AddField(
        IntegerField(
            'iterations',
            default=1,
            required=False,
            description='Number of iterations to '
            'run the test.'))
    self.assertEqual(len(self.settings.fields), 1)
    # Adding the same field twice raises an exception.
    self.assertRaises(Exception, self.settings.AddField, (IntegerField(
        'iterations',
        default=1,
        required=False,
        description='Number of iterations to run '
        'the test.')))
    res = self.settings.fields['iterations']
    self.assertIsInstance(res, IntegerField)
    self.assertEqual(res.Get(), 1)

  def test_set_field(self):
    self.assertEqual(self.settings.fields, {})
    self.settings.AddField(
        IntegerField(
            'iterations',
            default=1,
            required=False,
            description='Number of iterations to run the '
            'test.'))
    res = self.settings.fields['iterations']
    self.assertEqual(res.Get(), 1)

    self.settings.SetField('iterations', 10)
    res = self.settings.fields['iterations']
    self.assertEqual(res.Get(), 10)

    # Setting a field that's not there raises an exception.
    self.assertRaises(Exception, self.settings.SetField, 'remote',
                      'lumpy1.cros')

    self.settings.AddField(
        ListField(
            'remote',
            default=[],
            description="A comma-separated list of ip's of "
            'chromeos devices to run '
            'experiments on.'))
    self.assertTrue(isinstance(self.settings.fields, dict))
    self.assertEqual(len(self.settings.fields), 2)
    res = self.settings.fields['remote']
    self.assertEqual(res.Get(), [])
    self.settings.SetField('remote', 'lumpy1.cros', append=True)
    self.settings.SetField('remote', 'lumpy2.cros', append=True)
    res = self.settings.fields['remote']
    self.assertEqual(res.Get(), ['lumpy1.cros', 'lumpy2.cros'])

  def test_get_field(self):
    # Getting a field that's not there raises an exception.
    self.assertRaises(Exception, self.settings.GetField, 'iterations')

    # Getting a required field that hasn't been assigned raises an exception.
    self.settings.AddField(
        IntegerField(
            'iterations',
            required=True,
            description='Number of iterations to '
            'run the test.'))
    self.assertIsNotNone(self.settings.fields['iterations'])
    self.assertRaises(Exception, self.settings.GetField, 'iterations')

    # Set the value, then get it.
    self.settings.SetField('iterations', 5)
    res = self.settings.GetField('iterations')
    self.assertEqual(res, 5)

  def test_inherit(self):
    parent_settings = settings_factory.SettingsFactory().GetSettings(
        'global', 'global')
    label_settings = settings_factory.SettingsFactory().GetSettings(
        'label', 'label')
    self.assertEqual(parent_settings.GetField('chromeos_root'), '')
    self.assertEqual(label_settings.GetField('chromeos_root'), '')
    self.assertIsNone(label_settings.parent)

    parent_settings.SetField('chromeos_root', '/tmp/chromeos')
    label_settings.SetParentSettings(parent_settings)
    self.assertEqual(parent_settings.GetField('chromeos_root'), '/tmp/chromeos')
    self.assertEqual(label_settings.GetField('chromeos_root'), '')
    label_settings.Inherit()
    self.assertEqual(label_settings.GetField('chromeos_root'), '/tmp/chromeos')

  def test_override(self):
    self.settings.AddField(
        ListField(
            'email',
            default=[],
            description='Space-seperated'
            'list of email addresses to send '
            'email to.'))

    global_settings = settings_factory.SettingsFactory().GetSettings(
        'global', 'global')

    global_settings.SetField('email', 'john.doe@google.com', append=True)
    global_settings.SetField('email', 'jane.smith@google.com', append=True)

    res = self.settings.GetField('email')
    self.assertEqual(res, [])

    self.settings.Override(global_settings)
    res = self.settings.GetField('email')
    self.assertEqual(res, ['john.doe@google.com', 'jane.smith@google.com'])

  def test_validate(self):

    self.settings.AddField(
        IntegerField(
            'iterations',
            required=True,
            description='Number of iterations '
            'to run the test.'))
    self.settings.AddField(
        ListField(
            'remote',
            default=[],
            required=True,
            description='A comma-separated list '
            "of ip's of chromeos "
            'devices to run experiments on.'))
    self.settings.AddField(
        ListField(
            'email',
            default=[],
            description='Space-seperated'
            'list of email addresses to '
            'send email to.'))

    # 'required' fields have not been assigned; should raise an exception.
    self.assertRaises(Exception, self.settings.Validate)
    self.settings.SetField('iterations', 2)
    self.settings.SetField('remote', 'x86-alex.cros', append=True)
    # Should run without exception now.
    self.settings.Validate()

  @mock.patch.object(logger, 'GetLogger')
  @mock.patch.object(download_images.ImageDownloader, 'Run')
  @mock.patch.object(download_images, 'ImageDownloader')
  def test_get_xbuddy_path(self, mock_downloader, mock_run, mock_logger):

    mock_run.return_value = 'fake_xbuddy_translation'
    mock_downloader.Run = mock_run
    board = 'lumpy'
    chromeos_root = '/tmp/chromeos'
    log_level = 'average'

    trybot_str = 'trybot-lumpy-paladin/R34-5417.0.0-b1506'
    official_str = 'lumpy-release/R34-5417.0.0'
    xbuddy_str = 'latest-dev'
    autotest_path = ''
    debug_path = ''
    download_debug = False

    self.settings.GetXbuddyPath(trybot_str, autotest_path, debug_path, board,
                                chromeos_root, log_level, download_debug)
    self.assertEqual(mock_run.call_count, 1)
    self.assertEqual(mock_run.call_args_list[0][0], (
        '/tmp/chromeos',
        'remote/trybot-lumpy-paladin/R34-5417.0.0-b1506',
        '',
        '',
        False,
    ))

    mock_run.reset_mock()
    self.settings.GetXbuddyPath(official_str, autotest_path, debug_path, board,
                                chromeos_root, log_level, download_debug)
    self.assertEqual(mock_run.call_count, 1)
    self.assertEqual(
        mock_run.call_args_list[0][0],
        ('/tmp/chromeos', 'remote/lumpy-release/R34-5417.0.0', '', '', False))

    mock_run.reset_mock()
    self.settings.GetXbuddyPath(xbuddy_str, autotest_path, debug_path, board,
                                chromeos_root, log_level, download_debug)
    self.assertEqual(mock_run.call_count, 1)
    self.assertEqual(
        mock_run.call_args_list[0][0],
        ('/tmp/chromeos', 'remote/lumpy/latest-dev', '', '', False))

    if mock_logger:
      return


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