#!/bin/bash /usr/scripts/python.sh
# -*- coding: utf-8 -*-
#
# This file is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This file is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA.
"""Contient la définition et les outils pour bosser avec
les ports.

C'est essentiellement une couche d'abstraction, les fonctions
utiles sont appelées avec les switches."""

import netaddr

from .mac import MACFactory, bin_to_mac

class HPSwitchPort(object):
    """Classe représentant le port d'un switch"""

    def __init__(self, num, parent, ptype=None):
        """Permet de lier un port au switch parent."""
        self.__num = num
        self.__ptype = ptype
        self.__parent = parent
        self.__macs = []
        self.__multicast = []
        self.__vlans = []
        self.__oper = False
        self.__admin = False
        self.__alias = None
        self.__eth = None

    def name(self):
        """Retourne le nom du port"""

        return "%s%02d" % (self.__parent.name(), self.__num)

    def get_vlans(self):
        """Retourne les vlans du port"""
        return self.__vlans

    def add_vlan(self, vlan):
        """Ajoute le vlan à la liste"""
        self.__vlans.append(vlan)

    def purge_vlans(self):
        """Purge la liste des vlans connus du port"""
        self.__vlans = []

    def get_eth(self):
        """Récupère l'alias du port"""
        if self.__eth is None:
            self.__parent.update_eth_speed()
        return self.__eth

    def set_eth(self, val):
        """Affecte le nom"""
        self.__eth = val

    def get_alias(self):
        """Récupère l'alias du port"""
        if self.__alias is None:
            self.__parent.update_ports_aliases()
        return self.__alias

    def set_alias(self, alias):
        """Affecte le nom"""
        self.__alias = alias

    def append_mac(self, mac):
        """Ajoute une mac au port"""
        self.__macs.append(MACFactory.register_mac(bin_to_mac(mac), self))

    def get_macs(self, update=False):
        """Récupère les adresses mac depuis le parent"""
        if not self.__macs or update:
            # On boucle sur les macs et on les sépare du parent actuel (vu
            # qu'on va régénérer sa liste de macs).
            self.flush_macs()

            __ret = self.__parent.client.walk('hpSwitchPortFdbAddress.%d' % (self.__num,))
            self.__macs = [MACFactory.register_mac(bin_to_mac(ret['val']), self) for ret in __ret]
        return self.__macs

    def flush_macs(self):
        """Vire les macs"""
        if not self.__macs:
            return True

        for mac in self.__macs:
            mac.remove_parent(self)

        self.__macs = []
        return True

    def append_multicast(self, multi_ip):
        """Ajoute l'IP aux multicasts"""
        self.__multicast.append(netaddr.IPAddress(multi_ip))

    @property
    def multicast(self):
        """Retourne les ip multicast liées au port."""
        return self.__multicast

    def flush_multicast(self):
        """Vire les infos sur le multicast."""
        self.__multicast = []

    @property
    def parent(self):
        """Property sur __parent"""
        return self.__parent

    @property
    def oper(self):
        """Retourne l'oper status"""
        return self.__oper

    @property
    def admin(self):
        """Retourne l'admin status"""
        return self.__admin

    @admin.setter
    def admin(self, stat):
        """Met à jour l'admin status. Si stat n'est pas bon, met 3 (testing)"""
        try:
            stat = int(stat)
        except TypeError:
            stat = 3

        self.__admin = stat

    @oper.setter
    def oper(self, stat):
        """Met à jour l'oper status. Si stat n'est pas bon, met 4 (unknown)"""
        try:
            stat = int(stat)
        except TypeError:
            stat = 4

        self.__oper = stat

