from .Framework import ExecutableService
import os.path

class IPAliases(ExecutableService):

    is_cpanel_check_file = '/usr/local/cpanel/version'
    wwwacct_file = '/etc/wwwacct.conf'
    mainip_file = '/var/cpanel/mainip'
    additional_ips_file = '/etc/ips'

    def __init__(self):
        self.command = None
        super(IPAliases, self).__init__()

    def get_data(self):
        if not self.__is_cpanel():
            # /usr/local/cpanel/version does not exist
            return 0

        try:
            ethdev = self.__get_ethdev()
        except IOError:
            # The /etc/wwwacct.conf file didn't open. Is this a cPanel server?
            return 0

        main_ip = self.__get_main_ip()
        if not main_ip:
            # It has to have a main IP set for an accurate check
            return 0

        # We don't really care if this is empty as they may not have multiple IPs
        additional_ips = self.__get_additional_ips()

        all_ips = [main_ip] + additional_ips

        return self.__check_ips(ethdev, all_ips)

    def __is_cpanel(self):
        return os.path.isfile(self.is_cpanel_check_file)

    def __get_ethdev(self):
        with open(self.wwwacct_file) as f:
            for line in f:
                line_parts = line.split()
                if line_parts[0].strip() == 'ETHDEV':
                    return line_parts[1].strip()

    def __get_main_ip(self):
        try:
            with open(self.mainip_file) as f:
                return f.read().strip()
        except IOError:
            # The file couldn't be opened. Returning an empty string.
            return ''

    def __get_additional_ips(self):
        return_ips = []
        try:
            with open(self.additional_ips_file) as f:
                for line in f:
                    line = line.strip()
                    if line:
                        line_parts = line.split(':')
                        if len(line_parts) == 3:
                            # The lines in this file have 3 parts. We only need the first, but ignore invalide lines
                            return_ips.append(line_parts[0])
        except IOError:
            # The file couldn't be opened. Returning the empty list.
            pass

        return return_ips

    def __check_ips(self, ethdev, ip_addrs):
        self.command_list = self.parse_command('ip address show dev {dev}'.format(dev=ethdev))

        in_use_ips = []
        for line in self._get_raw_data():
            line = line.strip()
            if line:
                line_parts = line.split()
                if line_parts[0] == 'inet':
                    ip_addr = line_parts[1].split('/')[0]
                    if ip_addr:
                        in_use_ips.append(ip_addr)

        for ip_addr in ip_addrs:
            if ip_addr not in in_use_ips:
                return 0

        return 1