from __future__ import print_function, division, absolute_import

import os
import logging
log = logging.getLogger("rhsm-app.unittests." + __name__)

from subscription_manager import cpuinfo

from . import fixture

test_path = os.path.dirname(__file__)
CPUINFOS = "data/cpuinfo"

cpu_data_dir = os.path.join(test_path, CPUINFOS)


class BaseCpuInfo(fixture.SubManFixture):
    expected = {}
    cpuinfo_class = None

    def _test(self, name):
        cpud = self._load_cpuinfo(name)
        exp = self.expected[name]

        x = self.cpuinfo_class.from_proc_cpuinfo_string(cpud)

        if 'cpu_count' in exp:
            self.assertEqual(exp['cpu_count'], len(x.cpu_info.processors))
        if 'model' in exp:
            self.assertEqual(exp['model'], x.cpu_info.model)
        if 'machine' in exp:
            self.assertEqual(exp['machine'], x.cpu_info.common['machine'])

    def _load_cpuinfo(self, name):
        f = open(os.path.join(cpu_data_dir, name), 'r')
        cpuinfo_data = f.read()
        return cpuinfo_data

    def _test_fact_key(self, key):
        bad_letters = ' .   '

        for bad_letter in bad_letters:
            self.assertFalse(bad_letter in key)


class TestX86_64CpuInfo(BaseCpuInfo):
    expected = {'x86_64-dell-e4310-1socket-2core-4cpu': {'cpu_count': 4,
                                      'model': '37'},
                'x86_64-dell-t7600-2sockets-6core-24cpu': {'cpu_count': 24,
                                            'model': '45'},
                'x86_64-4socket-8core-64cpu': {'cpu_count': 64},
                'armv7-samsung-1socket-2core-2cpu': {}}
    cpuinfo_class = cpuinfo.X86_64CpuInfo

    def test_x86_64_dell_e4310(self):
        self._test('x86_64-dell-e4310-1socket-2core-4cpu')

    def test_x86_64_64cpu(self):
        self._test('x86_64-4socket-8core-64cpu')

    def test_x86_64_24cpu_dell_t7600(self):
        self._test('x86_64-dell-t7600-2sockets-6core-24cpu')

    def test_armv7(self):
        # verify we fail nicely when given a completely different /proc/cpuinfo
        self._test('armv7-samsung-1socket-2core-2cpu')


class TestPpc64CpuInfo(BaseCpuInfo):
    cpuinfo_class = cpuinfo.Ppc64CpuInfo
    expected = {'ppc64-power8-16cpu-kvm':
                    {'cpu_count': 16,
                     'platform': 'pSeries',
                     'model': 'IBM pSeries (emulated by qemu)'},
                'ppc64-power8-160cpu-powernv':
                    {'cpu_count': 160,
                     'platform': 'powerNV',
                     'model': '8247-22L'}}

    def test_ppc64_power8_160cpu_powernv(self):
        self._test('ppc64-power8-160cpu-powernv')

    def test_ppc64_power8_16cpu_kvm(self):
        self._test('ppc64-power8-16cpu-kvm')


class TestPpc64leCpuInfo(BaseCpuInfo):
    cpuinfo_class = cpuinfo.Ppc64CpuInfo
    expected = {'ppc64le-power8-16cpu-lpar':
                {'cpu_count': 16,
                 'platform': 'pSeries',
                 'model': 'IBM,8247-22L',
                 'machine': 'CHRP IBM,8247-22L'}
              }

    def test_ppc64le_power8_16cpu_lpar(self):
        self._test('ppc64le-power8-16cpu-lpar')


class TestAarch64CpuInfo(BaseCpuInfo):
    cpuinfo_class = cpuinfo.Aarch64CpuInfo
    expected = {'aarch64-mustang-dev-rhel7-1socket-8core-8cpu':
                    {'cpu_count': 8,
                     'model_name': 'AArch64 Processor rev 0 (aarch64)'},
                'aarch64-hp-moonshot-1socket-8core-8cpu':
                    {'cpu_count': 8,
                     'model_name': None}}

    def test_mustang(self):
        self._test('aarch64-mustang-dev-rhel7-1socket-8core-8cpu')

    def test_moonshot(self):
        self._test('aarch64-hp-moonshot-1socket-8core-8cpu')
