#!/usr/bin/env python3
# Copyright 2020 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.

"""
Unit tests for query_by_field.py

"""

import io
import sys
import unittest

import platform_json_unittest
import query_by_field


def _run_main(argv):
    """Run platform_json.main(argv), capturing and returning stdout."""
    original_stdout = sys.stdout
    capture_io = io.StringIO()
    sys.stdout = capture_io
    try:
        query_by_field.main(argv)
        return capture_io.getvalue()
    finally:
        capture_io.close()
        sys.stdout = original_stdout


class SingleOperatorTestCase(platform_json_unittest.AbstractMockConfigTestCase,
                             unittest.TestCase):
    """Test-case for using a single operator of each type."""
    def runTest(self):  # pylint: disable=invalid-name
        """Test each operator in isolation."""
        # Equality operator ('=')
        argv = ['field1=5', '-c', self.mock_filepath]
        expected = 'DEFAULTS\n'
        self.assertEqual(_run_main(argv), expected)

        # Inequality operator ('!=')
        argv = ['field1!=5', '-c', self.mock_filepath]
        expected = 'my_platform\nmy_parent\nmy_grandparent\n'
        self.assertEqual(_run_main(argv), expected)

        # Array membership operator (':')
        argv = ['fieldArray:elem2', '-c', self.mock_filepath]
        expected = 'my_platform\n'
        self.assertEqual(_run_main(argv), expected)

        # Array non-membership operator ('!:')
        argv = ['fieldArray!:elem5', '-c', self.mock_filepath]
        expected = 'my_platform\n'
        self.assertEqual(_run_main(argv), expected)

        # Numeric less-than operator ('<')
        argv = ['field1<2', '-c', self.mock_filepath]
        expected = 'my_platform (except my_model)\n'
        self.assertEqual(_run_main(argv), expected)

        # Numeric less-than-or-equal operator ('<=')
        argv = ['field1<=2', '-c', self.mock_filepath]
        expected = 'my_platform (except my_model)\nmy_parent\n'
        self.assertEqual(_run_main(argv), expected)

        # Numeric greater-than operator ('>')
        argv = ['field1>4', '-c', self.mock_filepath]
        expected = 'DEFAULTS\n'
        self.assertEqual(_run_main(argv), expected)

        # Numeric greater-than-or-equal operator ('>=')
        argv = ['field1>=4', '-c', self.mock_filepath]
        expected = 'DEFAULTS\nmy_platform (only my_model)\n'
        self.assertEqual(_run_main(argv), expected)


class OperatorTypeMismatchTestCase(platform_json_unittest.AbstractMockConfigTestCase,
                                   unittest.TestCase):
    """Test-case for exceptions being raised for operator-type mismatches."""
    def runTest(self):  # pylint: disable=invalid-name
        """Test each operator which can have invalid types."""
        # Array operators only make sense with array fields.
        for operator in (':', '!:'):
            query = 'field1%s1' % operator
            argv = [query, '-c', self.mock_filepath]
            with self.assertRaises(query_by_field.NotIterableError):
                _run_main(argv)

        # Numeric operators only make sense with numeric fields.
        for operator in ('<', '<=', '>', '>='):
            config_value_is_array = 'fieldArray%s1'
            config_value_is_string = 'platform%s1'
            expected_value_is_string = 'field1%sfoo'
            for fmt in (config_value_is_array, config_value_is_string,
                        expected_value_is_string):
                query = fmt % operator
                argv = [query, '-c', self.mock_filepath]
                with self.assertRaises(query_by_field.NotNumericError):
                    _run_main(argv)


class MultipleOperatorsTestCase(platform_json_unittest.AbstractMockConfigTestCase,
                                unittest.TestCase):
    """Test-case for using multiple operators."""
    def runTest(self):  # pylint: disable=invalid-name
        """Test using multiple operators."""
        argv = ['field1!=1', 'field1!=4', '-c', self.mock_filepath]
        expected = 'DEFAULTS\nmy_parent\nmy_grandparent\n'
        self.assertEqual(_run_main(argv), expected)


class ModelExceptionsTestCase(platform_json_unittest.AbstractMockConfigTestCase,
                              unittest.TestCase):
    """Test-case for when model overrides change whether a platform matches."""
    def runTest(self):  # pylint: disable=invalid-name
        """Test all variants of model exceptions."""
        # Check for when a platform does not match, except for one model
        argv = ['field1=4', '-c', self.mock_filepath]
        expected = 'my_platform (only my_model)\n'
        self.assertEqual(_run_main(argv), expected)

        # Check for when a platform matches, except for one model
        argv = ['field1=1', '-c', self.mock_filepath]
        expected = 'my_platform (except my_model)\n'
        self.assertEqual(_run_main(argv), expected)

        # Check for multiple model exceptions
        argv = ['field1=1', 'field2=2', '-c', self.mock_filepath]
        expected = 'my_platform (except my_model, my_model2)\n'
        self.assertEqual(_run_main(argv), expected)


class NoMatchesTestCase(platform_json_unittest.AbstractMockConfigTestCase,
                        unittest.TestCase):
    """Test-case for when no platforms match the query."""
    def runTest(self):  #pylint: disable=invalid-name
        """Run script with a bogus query."""
        argv = ['field1=1337', '-c', self.mock_filepath]
        expected = 'No platforms matched.\n'
        self.assertEqual(_run_main(argv), expected)


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