"""
 *
 * This file is part of rasdaman community.
 *
 * Rasdaman community 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 3 of the License, or
 * (at your option) any later version.
 *
 * Rasdaman community 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 rasdaman community.  If not, see <http://www.gnu.org/licenses/>.
 *
 * Copyright 2003 - 2016 Peter Baumann / rasdaman GmbH.
 *
 * For more information please see <http://www.rasdaman.org>
 * or contact Peter Baumann via <baumann@rasdaman.com>.
 *
"""
from .abstractosinstaller import OSInstaller
from .centos7 import CentOS7TPInstaller
from .centos8 import CentOS8TPInstaller
from .debian9 import Debian9TPInstaller
from .debian10 import Debian10TPInstaller
from .ubuntu1604 import Ubuntu1604TpInstaller
from .ubuntu1804 import Ubuntu1804TpInstaller
from .ubuntu2004 import Ubuntu2004TpInstaller
from .ubuntu2204 import Ubuntu2204TpInstaller
from util.distrowrapper import DistroTypes, DistroWrapper


class OSNotSupported(Exception):
    def __init__(self, os_name):
        """
        Error that occurs when we do not know how to deal with the given OS
        :param str os_name: the os name
        """
        self.os_name = os_name

    def __str__(self):
        return "Your Linux distro could not be detected or is not supported. Found distro name: " + self.os_name


class OSVersionNotSupported(Exception):
    def __init__(self, os_name, os_version):
        """
        Error that occurs when we do not support the given OS version
        :param str os_name: the os name
        :param str os_version: the os version
        """
        self.os_name = os_name
        self.os_version = os_version

    def __str__(self):
        return self.os_name + " version " + self.os_version + " is not supported."


class DependenciesInstallerFactory:
    @staticmethod
    def get_installer(profile):
        """
        Returns the OS installer based on the OS name and version.
        :param Profile profile: installation profile
        :rtype: OSInstaller
        """
        distro = DistroWrapper()

        # debian
        if distro.distro_type == DistroTypes.DEBIAN:
            if distro.distro_version < 9:
                raise OSVersionNotSupported(distro.distro_name, distro.distro_version)
            elif distro.distro_version < 10:
                return Debian9TPInstaller(profile)
            elif distro.distro_version < 11:
                return Debian10TPInstaller(profile)
            else:
                raise OSVersionNotSupported(distro.distro_name, distro.distro_version)
        # ubuntu
        elif distro.distro_type == DistroTypes.UBUNTU:
            if distro.distro_version < 16.04:
                raise OSVersionNotSupported(distro.distro_name, distro.distro_version)
            elif distro.distro_version < 16.10:
                return Ubuntu1604TpInstaller(profile)
            elif distro.distro_version > 18.03 and distro.distro_version < 18.05:
                return Ubuntu1804TpInstaller(profile)
            elif distro.distro_version > 20.03 and distro.distro_version < 20.05:
                return Ubuntu2004TpInstaller(profile)
            elif distro.distro_version > 22.03 and distro.distro_version < 22.05:
                return Ubuntu2204TpInstaller(profile)
            else:
                raise OSVersionNotSupported(distro.distro_name, distro.distro_version)
        # centos
        elif distro.distro_type == DistroTypes.CENTOS:
            if distro.distro_version < 7:
                raise OSVersionNotSupported(distro.distro_name, distro.distro_version)
            elif distro.distro_version < 8:
                return CentOS7TPInstaller(profile)
            elif distro.distro_version < 9:
                return CentOS8TPInstaller(profile)
            else:
                raise OSVersionNotSupported(distro.distro_name, distro.distro_version)
        else:
            raise OSNotSupported(distro.distro_name)
