import ntpath

from parallels.core import messages
from parallels.core.utils import windows_utils
from parallels.core.utils.paths import web_paths
from parallels.core.utils.paths.copy_web_content import BaseWebPathConverter


class WindowsTargetWebPathConverter(BaseWebPathConverter):
    """Class to convert abstract path descriptor to concrete path for rsync on target server"""

    def __init__(self, is_rsync=False):
        self._is_rsync = is_rsync

    def expand(self, path, server):
        """Convert abstract path descriptor to concrete absolute path for target server

        :type path: parallels.core.utils.web_paths.WebHostingPath
        :type server: parallels.plesk.connections.target_server.PleskTargetServer
        :rtype: str | unicode
        """
        if isinstance(path, web_paths.AbsolutePath):
            return self._convert_path(path.absolute_path)
        elif isinstance(path, web_paths.WebspacePath):
            return self._convert_path(self._expand_webspace_path(path, server))
        elif isinstance(path, web_paths.SitePath):
            return self._convert_path(self._expand_site_path(path, server))
        else:
            assert False, messages.UNSUPPORTED_SOURCE_WEB_PATH_TYPE

    def _convert_path(self, path):
        if self._is_rsync:
            return windows_utils.convert_path_to_cygwin(path)
        return path

    def _expand_webspace_path(self, path, server):
        """
        :type path: parallels.core.utils.paths.web_paths.WebspacePath
        :type server: parallels.plesk.connections.target_server.PleskTargetServer
        :rtype: str | unicode
        """
        name_idna = path.webspace.name.encode('idna')
        webspace_root_path = ntpath.join(server.vhosts_dir, name_idna)
        webpace_wwwroot_path = ntpath.join(webspace_root_path, path.webspace.www_root)
        dot_plesk_dir = ntpath.join(webspace_root_path, '.plesk')

        if isinstance(path, web_paths.WebspaceRoot):
            return webspace_root_path
        elif isinstance(path, web_paths.WebspaceDocumentRoot):
            return webpace_wwwroot_path
        elif isinstance(path, web_paths.WebspaceSSLDocumentRoot):
            return ntpath.join(webspace_root_path, 'httpsdocs', name_idna)
        elif isinstance(path, web_paths.WebspaceMainDomainPrivate):
            return ntpath.join(webspace_root_path, 'private', name_idna)
        elif isinstance(path, web_paths.WebspaceLogs):
            return ntpath.join(webspace_root_path, 'logs')
        elif isinstance(path, web_paths.WebspaceMainDomainStatistics):
            return ntpath.join(dot_plesk_dir, 'statistics', name_idna)
        elif isinstance(path, web_paths.WebspaceSecurityFile):
            return ntpath.join(dot_plesk_dir, '.Security')
        elif isinstance(path, web_paths.WebspaceAdditionalSecurityFile):
            return ntpath.join(dot_plesk_dir, path.security_file_path)
        elif isinstance(path, web_paths.WebspacePathTemplate):
            return self._expand_webspace_template(path, server)
        else:
            assert False, messages.UNSUPPORTED_SOURCE_WEB_PATH_TYPE

    def _expand_site_path(self, path, server):
        """
        :type path: parallels.core.utils.paths.web_paths.SitePath
        :type server: parallels.plesk.connections.target_server.PleskTargetServer
        :rtype: str | unicode
        """
        webspace_name_idna = path.webspace.name.encode('idna')
        site_name_idna = path.site.name.encode('idna')
        webspace_root_path = ntpath.join(server.vhosts_dir, webspace_name_idna)
        dot_plesk_dir = ntpath.join(webspace_root_path, '.plesk')

        if isinstance(path, web_paths.SiteDocumentRoot):
            return ntpath.join(webspace_root_path, path.site.www_root)
        elif isinstance(path, web_paths.SitePrivate):
            return ntpath.join(webspace_root_path, 'private', site_name_idna)
        elif isinstance(path, web_paths.SiteStatistics):
            return ntpath.join(dot_plesk_dir, 'statistics', site_name_idna)
        elif isinstance(path, web_paths.SitePathTemplate):
            return self._expand_site_template(path, server)
        else:
            assert False, messages.UNSUPPORTED_SOURCE_WEB_PATH_TYPE

    def _expand_webspace_template(self, path, server):
        """
        :type path: parallels.core.utils.web_paths.WebspacePathTemplate
        :type server: parallels.plesk.connections.target_server.PleskTargetServer
        :rtype: str | unicode
        """
        variable_paths = {
            'webspace_root': web_paths.WebspaceRoot,
            'document_root': web_paths.WebspaceDocumentRoot,
            'ssl_document_root': web_paths.WebspaceSSLDocumentRoot,
            'main_domain_private': web_paths.WebspaceMainDomainPrivate,
            'logs': web_paths.WebspaceLogs,
            'main_domain_statistics': web_paths.WebspaceMainDomainStatistics,
        }
        variables = {}
        for var_name, path_class in variable_paths.items():
            variables[var_name] = self.expand(path_class(path.webspace), server)
        variables['webspace'] = path.webspace.name
        variables['webspace_idn'] = path.webspace.name.encode('idna')

        return path.template.format(**variables)

    def _expand_site_template(self, path, server):
        """
        :type path: parallels.core.utils.web_paths.SitePathTemplate
        :type server: parallels.plesk.connections.target_server.PleskTargetServer
        :rtype: str | unicode
        """
        webspace_variable_paths = {
            'webspace_root': web_paths.WebspaceRoot,
            'webspace_document_root': web_paths.WebspaceDocumentRoot,
            'webspace_ssl_document_root': web_paths.WebspaceSSLDocumentRoot,
            'webspace_logs': web_paths.WebspaceLogs,
        }
        site_variable_paths = {
            'document_root': web_paths.SiteDocumentRoot,
            'private': web_paths.SitePrivate,
            'statistics': web_paths.SiteStatistics,
        }
        variables = {}
        for var_name, path_class in webspace_variable_paths.items():
            variables[var_name] = self.expand(
                path_class(path.webspace), server
            )
        for var_name, path_class in site_variable_paths.items():
            variables[var_name] = self.expand(
                path_class(path.webspace, path.site), server
            )
        variables['webspace'] = path.webspace.name
        variables['webspace_idn'] = path.webspace.name.encode('idna')
        variables['site'] = path.site.name
        variables['site_idn'] = path.site.name.encode('idna')

        return path.template.format(**variables)
