from parallels.core.utils.common.threading_utils import synchronized
from parallels.plesk.source.web.config import FileTransportOption


class DomainType(object):
    SUBSCRIPTION = 'subscription'
    ADDON = 'addon-domain'
    SUBDOMAIN = 'subdomain'


class SiteInfoStorage(object):
    KEY_SITE_NAME = 'site_name'
    KEY_BASE_URL = 'base_url'
    KEY_DOCUMENT_ROOT = 'document_root'
    KEY_ROOT_PATH = 'root_path'
    KEY_FILESYSTEM_ROOT_PATH = 'filesystem_root_path'
    KEY_APPLICATIONS = 'applications'
    KEY_FILES = 'files'
    KEY_TARGET_SUBSCRIPTION = 'target-subscription'
    KEY_TARGET_DOMAIN_TYPE = 'target-domain-type'
    KEY_TARGET_DOCUMENT_ROOT = 'target-document-root'
    KEY_TARGET_SYSUSER_LOGIN = 'target-sysuser-login'
    KEY_TARGET_DOMAIN_ID = 'target-domain-id'
    KEY_TARGET_DOMAIN_NAME = 'target-domain-name'
    KEY_TARGET_IP_ADDRESSES = 'target-ip-addresses'
    KEY_TARGET_DOMAIN_DISPLAY_NAME = 'target-domain-display-name'
    KEY_HOSTING_SSL = 'hosting-ssl'
    KEY_FTP_VERSION = 'ftp-version'
    KEY_PHP_VERSION = 'php-version'
    KEY_IS_WINDOWS = 'is-windows'
    KEY_FILE_TRANSPORT = 'file-transfer-mode'

    def __init__(self, data_storage):
        """
        :type data_storage: parallels.core.utils.data_storage.DataStorageBase
        """
        self._data_storage = data_storage

    def set_site_name(self, site_name):
        """Set domain name of migrated site

        :type site_name: str | unicode
        :rtype: None
        """
        self._data_storage.set_data(self.KEY_SITE_NAME, site_name)

    def get_site_name(self):
        """Get domain name of migrated site

        :rtype: str | unicode | None
        """
        return self._data_storage.get_data(self.KEY_SITE_NAME)

    def set_base_url(self, base_url):
        """Set base URL of migrated site

        :type base_url: str | unicode
        :rtype: None
        """
        self._data_storage.set_data(self.KEY_BASE_URL, base_url)

    def get_base_url(self):
        """Get base URL of migrated site

        :rtype: str | unicode
        """
        return self._data_storage.get_data(self.KEY_BASE_URL)

    def set_root_path(self, root_path):
        """Set absolute path from which migrator scans for content (builds files tree and looks for applications)

        Usually it is equals to home directory of a user, e.g. "/var/www/vhosts/example.com",
        but it could be overridden by special configuration option.

        :type root_path: str | unicode
        :rtype: None
        """
        self._data_storage.set_data(self.KEY_ROOT_PATH, root_path)

    def set_filesystem_root_path(self, filesystem_root_path):
        """Set the most top absolute path which is available by FTP/SSH

        For SSH it is usually equals to "/"
        For FTP or chrooted SSH it is usually equals to home directory of a user, e.g. "/var/www/vhosts/example.com"

        :type filesystem_root_path: str | unicode
        :rtype: None
        """
        self._data_storage.set_data(self.KEY_FILESYSTEM_ROOT_PATH, filesystem_root_path)

    def get_filesystem_root_path(self):
        """Get the most top absolute path which is available by FTP/SSH

        For SSH it is usually equals to "/"
        For FTP or chrooted SSH it is usually equals to home directory of a user, e.g. "/var/www/vhosts/example.com"

        :rtype: str | unicode
        """
        return self._data_storage.get_data(self.KEY_FILESYSTEM_ROOT_PATH)

    def set_document_root(self, document_root):
        """Set document root of migrated site (relative to directory available after connecting to source by FTP/SSH)

        :type document_root: str | unicode
        :rtype: None
        """
        self._data_storage.set_data(self.KEY_DOCUMENT_ROOT, document_root)

    def get_document_root(self):
        """Get document root of migrated site (relative to directory available after connecting to source by FTP/SSH)

        :rtype: str | unicode
        """
        return self._data_storage.get_data(self.KEY_DOCUMENT_ROOT)

    def get_applications(self):
        """Get application paths on specified source

        Returns dictionary, key is application ID, value is a list of paths where that application is installed.

        Example:
        {
            'Drupal': ['/var/www/vhosts/multiapp.tld/httpdocs/drupal/sites/default'],
            'PrestaShop': [],
            'Magento': []
        }

        :rtype: dict[str | unicode, list[str | unicode]]
        """
        return self._data_storage.get_data(self.KEY_APPLICATIONS)

    @synchronized
    def set_applications(self, application_paths):
        """
        :type application_paths: dict[str | unicode, list[str | unicode]]
        :rtype: None
        """
        self._data_storage.set_data(self.KEY_APPLICATIONS, application_paths)

    def has_applications(self):
        """Check whether the storage already contains list of application paths

        :rtype: bool
        """
        return self.get_applications() is not None

    def get_files(self):
        """Get files tree on the source server"""
        return self._data_storage.get_data(self.KEY_FILES)

    def set_files(self, files):
        """Set files tree on the source server

        :rtype: None
        """
        self._data_storage.set_data(self.KEY_FILES, files)

    def has_files(self):
        """Check whether the storage already contains files tree

        :rtype: bool
        """
        return self.get_files() is not None

    def set_target_subscription(self, subscription_name):
        """Set name of subscription to which site is migrated

        :type subscription_name: str | unicode
        :rtype: None
        """
        self._data_storage.set_data(self.KEY_TARGET_SUBSCRIPTION, subscription_name)

    def get_target_subscription(self):
        """Get name of subscription to which site is migrated

        :rtype: str | unicode | None
        """
        return self._data_storage.get_data(self.KEY_TARGET_SUBSCRIPTION)

    def set_target_domain_type(self, domain_type):
        """Set type of domain (subscription, addon domain, subdomain) to which site is migrated

        :type domain_type: str | unicode
        :rtype: None
        """
        self._data_storage.set_data(self.KEY_TARGET_DOMAIN_TYPE, domain_type)

    def get_target_domain_type(self):
        """Get type of domain (subscription, addon domain, subdomain) to which site is migrated

        :rtype: str | unicode | None
        """
        return self._data_storage.get_data(self.KEY_TARGET_DOMAIN_TYPE)

    def set_target_domain_id(self, domain_id):
        """Set domain id (subscription, addon domain, subdomain) to which site is migrated

        :type domain_id: int
        :rtype: None
        """
        self._data_storage.set_data(self.KEY_TARGET_DOMAIN_ID, domain_id)

    def get_target_domain_id(self):
        """Get domain id (subscription, addon domain, subdomain) to which site is migrated

        :rtype: int | None
        """
        return self._data_storage.get_data(self.KEY_TARGET_DOMAIN_ID)

    def set_target_domain_name(self, domain_name):
        """Set domain name to which site is migrated

        :type domain_name: str | unicode
        :rtype: None
        """
        self._data_storage.set_data(self.KEY_TARGET_DOMAIN_NAME, domain_name)

    def get_target_domain_name(self):
        """Get domain name to which site is migrated

        :rtype: str | unicode | None
        """
        return self._data_storage.get_data(self.KEY_TARGET_DOMAIN_NAME)

    def set_target_document_root(self, document_root):
        """Set document root of domain to which site is migrated

        :type document_root: str | unicode
        :rtype: None
        """
        self._data_storage.set_data(self.KEY_TARGET_DOCUMENT_ROOT, document_root)

    def get_target_document_root(self):
        """Get document root of domain to which site is migrated

        :rtype: str | unicode | None
        """
        return self._data_storage.get_data(self.KEY_TARGET_DOCUMENT_ROOT)

    def set_target_sysuser_login(self, sysuser_login):
        """Set system user login of domain to which site is migrated

        :type sysuser_login: str | unicode
        :rtype: None
        """
        self._data_storage.set_data(self.KEY_TARGET_SYSUSER_LOGIN, sysuser_login)

    def get_target_sysuser_login(self):
        """Get system user login of domain to which site is migrated

        :rtype: str | unicode | None
        """
        return self._data_storage.get_data(self.KEY_TARGET_SYSUSER_LOGIN)

    def set_target_ip_addresses(self, ip_addresses):
        """Set IP addresses of domain to which site is migrated

        :type ip_addresses: list[str | unicode]
        :rtype: None
        """
        self._data_storage.set_data(self.KEY_TARGET_IP_ADDRESSES, ip_addresses)

    def get_target_ip_addresses(self):
        """Get IP addresses of domain to which site is migrated

        :rtype: list[str | unicode]
        """
        return self._data_storage.get_data(self.KEY_TARGET_IP_ADDRESSES)

    def set_target_hosting_ssl(self, hosting_ssl):
        """Set ssl enabled flag of domain to which site is migrated

        :type hosting_ssl: bool
        :rtype: None
        """
        self._data_storage.set_data(self.KEY_HOSTING_SSL, hosting_ssl)

    def get_target_hosting_ssl(self):
        """Get ssl enabled flag of domain to which site is migrated

        :rtype: bool
        """
        return self._data_storage.get_data(self.KEY_HOSTING_SSL)

    def set_target_domain_display_name(self, display_name):
        """Set display name of domain to which site is migrated

        :type display_name: str | unicode
        :rtype: None
        """
        self._data_storage.set_data(self.KEY_TARGET_DOMAIN_DISPLAY_NAME, display_name)

    def get_target_domain_display_name(self):
        """Get display name of domain to which site is migrated

        :rtype: str | unicode
        """
        return self._data_storage.get_data(self.KEY_TARGET_DOMAIN_DISPLAY_NAME)

    def set_ftp_version(self, ftp_version):
        """Set version of FTP server which was detected on source web site

        :type ftp_version: str | unicode
        :rtype: None
        """
        self._data_storage.set_data(self.KEY_FTP_VERSION, ftp_version)

    def get_ftp_version(self):
        """Get version of FTP server which was detected on source web site

        :rtype: str | unicode | None
        """
        return self._data_storage.get_data(self.KEY_FTP_VERSION)

    def set_php_version(self, php_version):
        """Set version of PHP on source web site

        :type php_version: str | unicode
        :rtype: None
        """
        self._data_storage.set_data(self.KEY_PHP_VERSION, php_version)

    def get_php_version(self):
        """Get version of PHP on source web site

        :rtype: str | unicode | None
        """
        return self._data_storage.get_data(self.KEY_PHP_VERSION)

    def set_is_windows(self, is_windows):
        """Set source OS type Windows or not

        :type is_windows: str | unicode
        :rtype: None
        """
        self._data_storage.set_data(self.KEY_IS_WINDOWS, is_windows)

    def get_is_windows(self):
        """Get source OS type Windows or not

        :rtype: bool | None
        """
        return self._data_storage.get_data(self.KEY_IS_WINDOWS)

    def set_file_transport(self, file_transport):
        """Set way to transfer files: one of 'FileTransportOption.FTP' or 'FileTransportOption.SSH' constants

        :type file_transport: str | unicode
        :rtype: None
        """
        self._data_storage.set_data(self.KEY_FILE_TRANSPORT, file_transport)

    def get_file_transport(self):
        """Get way to transfer files

        :rtype: str | unicode
        """
        return self._data_storage.get_data(
            self.KEY_FILE_TRANSPORT,
            # for compatibility with sessions created by old versions of migrator:
            # all of these sessions always used FTP as file transport
            default=FileTransportOption.FTP
        )
