'''
Unit tests for the RiscvProfile class
'''
from unittest.mock import mock_open, patch
from DistUpgrade.RiscvProfile import (RiscvProfile, RiscvProfileException)


class TestRiscvProfile:
    """
    Unit tests for the RiscvProfile class
    """

    def test_linux_supported(self):
        """
        Test the set of Linux supported extensions
        """
        actual = RiscvProfile('rv64gc').linux_supported()
        expected = RiscvProfile('rv64gc').rva23_to_check()

        for ext in expected:
            assert ext in actual

    def test_rva23_to_check(self):
        """
        Test the set of extensions used for RVA23U64 compliance check
        """
        actual = RiscvProfile('rv64gc').rva23_to_check()
        expected = [
            'i', 'm', 'a', 'f', 'd', 'c', 'v', 'zicbom', 'zicboz', 'ziccrse',
            'zicntr', 'zicond', 'zicsr', 'zihintntl', 'zihintpause', 'zihpm',
            'zimop', 'zawrs', 'zfa', 'zfhmin', 'zcb', 'zcmop', 'zvbb',
            'zvfhmin', 'zvkt', 'zkt', 'zba', 'zbb', 'zbs', 'zmmul', 'zaamo'
        ]

        for ext in expected:
            assert ext in actual

    def test_rva23_required(self):
        """
        Test the set of extensions required by the RVA23U64 profile
        """
        actual = RiscvProfile('rv64gc').rva23_required()
        expected = [
            'i', 'm', 'a', 'f', 'd', 'c', 'v', 'zic64b', 'zicbom', 'zicbop',
            'zicboz', 'ziccamoa', 'ziccif', 'zicclsm', 'ziccrse', 'zicntr',
            'zicond', 'zicsr', 'zihintntl', 'zihintpause', 'zihpm', 'zimop',
            'za64rs', 'zawrs', 'zfa', 'zfhmin', 'zcb', 'zcmop', 'zvbb',
            'zvfhmin', 'zvkt', 'zkt', 'zmmul', 'zaamo', 'zba', 'zbb', 'zbs',
            'supm'
        ]
        assert sorted(expected) == sorted(actual)

    @patch('builtins.open', new_callable=mock_open, read_data=b'isa: rv64im')
    def test_read_cpuinfo(self, mock_file):  # pylint: disable=unused-argument
        """
        Test deriving a profile from file /proc/cpuinfo
        """
        result = RiscvProfile.read_cpuinfo()
        actual = result.extensions
        expected = ['i', 'm', 'zmmul']
        assert sorted(expected) == sorted(actual)

    def test_assert_rva23_ready(self):
        """
        Test RVA23 readyness check
        """
        actual = False
        obj = RiscvProfile('rv64gc')
        try:
            obj.assert_rva23_ready()
        except RiscvProfileException:
            actual = True
        assert actual

        obj.extensions = obj.linux_supported()
        actual = False
        try:
            obj.assert_rva23_ready()
        except RiscvProfileException:
            actual = True
        assert not actual

        obj.extensions = obj.rva23_required()
        actual = False
        try:
            obj.assert_rva23_ready()
        except RiscvProfileException:
            actual = True
        assert not actual

    def test_bitness(self):
        """
        Test bitness
        """
        actual = RiscvProfile('RV32IMACZicsr_Zifencei').bitness
        expected = 32
        assert expected == actual

        actual = RiscvProfile('rv64gcsv39').bitness
        expected = 64
        assert expected == actual

    def test_extensions(self):
        """
        Test extensions
        """
        actual = RiscvProfile('RV32IMACZicsr_Zifencei').extensions
        expected = ['a', 'c', 'i', 'm', 'zaamo', 'zicsr', 'zifencei', 'zmmul']
        assert sorted(expected) == sorted(actual)

        actual = RiscvProfile(
                'rv64i2p1_m2p0_a2p1_f2p2_d2p2_c2p0_'
                'zicsr2p0_zifencei2p0_zmmul1p0_zaamo1p0_zalrsc1p0').extensions
        expected = ['a', 'c', 'd', 'f', 'i', 'm', 'zaamo', 'zalrsc',
                    'zicsr', 'zifencei', 'zmmul']
        assert sorted(expected) == sorted(actual)

        actual = RiscvProfile('rv64gcsv39').extensions
        expected = ['a', 'c', 'd', 'f', 'i', 'm', 'sv39', 'zicsr', 'zifencei',
                    'zaamo', 'zmmul']
        assert sorted(expected) == sorted(actual)
