# Copyright (c) 2015 iXsystems, Inc.
# All rights reserved.
# This file is a part of TrueNAS
# and may not be copied and/or distributed
# without the express permission of iXsystems.

import subprocess
from collections import defaultdict
from datetime import date, timedelta

from django.utils.translation import ugettext as _

from freenasUI.middleware.notifier import notifier
from freenasUI.system.alert import alertPlugins, Alert, BaseAlert
from freenasUI.support.utils import get_license
from freenasUI.truenas.ses import Enclosures


class LicenseStatusAlert(BaseAlert):

    def run(self):
        license, errmsg = get_license()
        alerts = []
        if license is None:
            return [Alert(
                Alert.CRIT,
                _('Your TrueNAS has no license, contact support.')
            )]

        proc = subprocess.Popen([
            '/usr/local/sbin/dmidecode',
            '-s', 'system-serial-number',
        ], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
        serial = proc.communicate()[0].strip()

        if license.system_serial != serial and license.system_serial_ha != serial:
            alerts.append(Alert(
                Alert.CRIT,
                _('System serial does not match license.'),
            ))

        hardware = notifier().get_chassis_hardware()
        hardware = hardware.replace('TRUENAS-', '')
        hardware = hardware.split('-')

        if hardware[0] == 'UNKNOWN':
            alerts.append(Alert(
                Alert.CRIT,
                _('You are not running TrueNAS on supported hardware.'),
            ))
        else:
            if hardware[0] == 'Z':
                if not license.model.startswith('Z'):
                    alerts.append(Alert(Alert.CRIT, _(
                        'Your license was issued for model "%s" but it was '
                        ' detected as Z series.'
                    ) % license.model))
            else:
                if hardware[0] in ('Z20', 'Z30', 'Z35', 'Z50'):
                    if hardware[0] != license.model:
                        alerts.append(Alert(Alert.CRIT, _(
                            'Your license was issued for model "%(license)s" '
                            'but it was detected as "%(model)s".'
                        ) % {
                            'model': hardware[0],
                            'license': license.model,
                        }))

            if 'HA' in hardware and not license.system_serial_ha:
                alerts.append(Alert(
                    Alert.CRIT, _(
                        'Your license was not issued for HA yet your hardware '
                        'was detected as HA.'
                    ),
                ))

        if license.addhw:

            encs = Enclosures()
            enc_nums = defaultdict(lambda: 0)
            # Echostream (Z model) has a built-in E16 which is not accounted for as
            # additional hardware, so skip the first one E16 found
            skip_e16 = license.model.startswith('Z')
            seen_ids = []
            for enc in encs:
                if enc.encid in seen_ids:
                    continue
                seen_ids.append(enc.encid)
                if enc.encname.find('ECStream 3U16') != -1:
                    if skip_e16:
                        skip_e16 = False
                        continue
                    enc_nums['E16'] += 1
                elif enc.encname.find('1729') != -1:
                    enc_nums['E24'] += 1
                elif enc.encname.find('QUANTA JB9 SIM') != -1:
                    enc_nums['E60'] += 1

            for addhw in license.addhw:
                # E16 Expansion shelf
                if addhw[1] == 1:
                    if enc_nums['E16'] != addhw[0]:
                        alerts.append(Alert(Alert.CRIT, _(
                            'License expects %(license)s units of E16 '
                            'Expansion shelf but found %(found)s.' % {
                                'license': addhw[0],
                                'found': enc_nums['E16'],
                            }
                        )))
                # E24 Expansion shelf
                if addhw[1] == 2:
                    if enc_nums['E24'] != addhw[0]:
                        alerts.append(Alert(Alert.CRIT, _(
                            'License expects %(license)s units of E24 '
                            'Expansion shelf but found %(found)s.' % {
                                'license': addhw[0],
                                'found': enc_nums['E24'],
                            }
                        )))
                # E60 Expansion shelf
                if addhw[1] == 3:
                    if enc_nums['E60'] != addhw[0]:
                        alerts.append(Alert(Alert.CRIT, _(
                            'License expects %(license)s units of E60 '
                            'Expansion shelf but found %(found)s.' % {
                                'license': addhw[0],
                                'found': enc_nums['E60'],
                            }
                        )))

        if license.contract_end < date.today() - timedelta(days=30):
            alerts.append(Alert(
                Alert.WARN,
                _('Your license is going to expire in %s.') % str(license.contract_end),
            ))

        return alerts


alertPlugins.register(LicenseStatusAlert)
