# -*- coding: utf-8 -*-

# Copyright 2008-2016 Mir Calculate. http://www.calculate-linux.org
#
#  Licensed under the Apache License, Version 2.0 (the "License");
#  you may not use this file except in compliance with the License.
#  You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
#  Unless required by applicable law or agreed to in writing, software
#  distributed under the License is distributed on an "AS IS" BASIS,
#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#  See the License for the specific language governing permissions and
#  limitations under the License.

import sys
import os
import re
from ..datavars import ReadonlyVariable
from ..utils.files import readFile, readLinesFile
from ..utils import device

_ = lambda x: x
from ..cl_lang import setLocalTranslate

setLocalTranslate('cl_lib3', sys.modules[__name__])


class VariableHrBoardModel(ReadonlyVariable):
    """
    Motherboard model
    """

    def get(self):
        return device.sysfs.read(
            device.sysfs.Path.Dmi, "board_name").strip()


class VariableHrBoardVendor(ReadonlyVariable):
    """
    Motherboard vendor
    """

    def get(self):
        """Get motherboard vendor"""
        return device.sysfs.read(
            device.sysfs.Path.Dmi, "board_vendor").strip()


class VariableHrCdromSet(ReadonlyVariable):
    """
    Cdrom device
    """
    type = "bool"

    def get(self):
        cdrom_blocks = (x for x in device.sysfs.listdir(device.sysfs.Path.Block,
                                                        fullpath=True)
                        if os.path.basename(x).startswith("sr"))
        for info in (device.udev.get_device_info(x) for x in cdrom_blocks):
            if device.udev.is_cdrom(info):
                return "on"
        return "off"


class VariableHrCpuNum(ReadonlyVariable):
    """
    Processors count
    """

    def init(self):
        self.label = _("Number of processors")

    def get(self):
        cpuinfo_file = "/proc/cpuinfo"
        return str(len([x for x in readLinesFile(cpuinfo_file) if x.startswith("processor")]) or 1)

class VariableHrCpuName(ReadonlyVariable):
    def get(self):
        cpuinfo_file = "/proc/cpuinfo"
        re_model_name = re.compile("^model name\s*:\s*(.*)$", re.M)
        res = re_model_name.search(readFile(cpuinfo_file))
        if res:
            return res.group(1).strip()
        return ""

class VariableHrVirtual(ReadonlyVariable):
    """
    Virtual machine name (virtualbox,vmware,qemu or "")
    """

    def get_lspci(self):
        virt_sys_dict = {'VirtualBox': 'virtualbox',
                         'VMware': 'vmware',
                         'Qumranet': 'qemu'}
        re_virt_info = re.compile("|".join(virt_sys_dict.keys()))
        devices = device.lspci(re_virt_info.search)
        for d in devices.values():
            name_res = re_virt_info.search(d['name'])
            if not name_res:
                name_res = re_virt_info.search(d['vendor'])
            if name_res:
                return virt_sys_dict[name_res.group()]

        return ""

    def get_cpuinfo(self):
        cpu_name = self.Get('hr_cpu_name')
        if "qemu" in cpu_name.lower():
            return "qemu"

    def get(self):
        return self.get_lspci() or self.get_cpuinfo() or ""


class VariableHrChassisType(ReadonlyVariable):
    """
    Тип устройства
    """
    # типы взяты из inxi
    Virtual = "virtual"
    Unknown = "unknown"
    Desktop = "desktop"
    PizzaBox = "pizza-box"
    Laptop = "laptop"
    Notebook = "notebook"
    Portable = "portable"
    Server = "server"
    Blade = "blade"

    def get(self):
        ct = device.sysfs.read(device.sysfs.Path.Dmi,
                                         "chassis_type").strip()
        if not ct.isdigit():
            return self.Unknown
        ct = int(ct)
        if ct == 1:
            return self.Virtual
        elif ct in (3,4,6,7,13,15,24):
            return self.Desktop
        elif ct in (9,10,16):
            return self.Laptop
        elif ct == 14:
            return self.Notebook
        elif ct in (8, 11):
            return self.Portable
        elif ct in (17,23,25):
            return self.Server
        elif ct in (27, 28, 29):
            return self.Blade
        elif ct == 5:
            return self.PizzaBox
        else:
            return self.Unknown

class VariableHrLaptop(ReadonlyVariable):
    """
    Laptop variable.

    If computer is notebook then variable contains vendor
    """

    def get(self):
        """Laptop vendor"""
        chassis_type = self.Get('hr_chassis_type')
        ChassisType = VariableHrChassisType
        if chassis_type in (ChassisType.Laptop,
                            ChassisType.Portable,
                            ChassisType.Notebook):
            board_vendor = device.sysfs.read(
                    device.sysfs.Path.Dmi, "board_vendor").strip()
            vendor = (board_vendor.partition(" ")[0]).lower()
            return vendor or "unknown"
        return ""


class VariableHrLaptopModel(ReadonlyVariable):
    """
    Laptop model name
    """

    def get(self):
        if self.Get('hr_laptop'):
            return device.sysfs.read(
                    device.sysfs.Path.Dmi, "board_name").strip() or "unknown"
        return ""


class VariableHrVideoName(ReadonlyVariable):
    """
    Video vendor full name
    """

    def init(self):
        self.label = _("Videocard")

    def get(self):
        pci_video = list(sorted(device.lspci("VGA compatible").items()))
        if pci_video:
            pci_video = pci_video[0][1]
            vendor = pci_video.get("vendor", "").split(" ")[0]
            name = pci_video.get("name", "")
            if "[" in name and "]" in name:
                name = name.partition("[")[2].partition("]")[0]
            return "{vendor} {name}".format(vendor=vendor, name=name)
        return ""


class VariableHrVideo(ReadonlyVariable):
    """
    Videocard vendor shortname (ati,nvidia,intel,via,vmware or other)
    """

    def get(self):
        """Videocard vendor"""
        line = self.Get('hr_video_name').lower()
        if any(x in line for x in ("nvidia", "geforce")):
            return "nvidia"
        if any(x in line for x in ("ati", "radeon")):
            return "ati"
        elif "intel" in line:
            return "intel"
        elif "via" in line:
            return "via"
        elif "vmware" in line:
            return "vmware"
        else:
            return "other"
