import json

from parallels.core import get_logger, safe_format
from parallels.core.reports.model.issue import Issue
from parallels.core.utils.clean_logging import clean_dict_args_for_log
from parallels.core.utils.safe_structures import safe_get_list
from parallels.plesk.source.web import messages
from parallels.plesk.source.web.utils.site_migration_exception import SiteMigrationError

logger = get_logger(__name__)


def create_config(source, folder):
    """Create configuration file for FTP migrator to transfer specified folder. Return the config as string.

    :type source: parallels.plesk.source.web.source.WebSource
    :type folder: parallels.plesk.source.web.migrated_folder.MigratedFolder
    :rtype: str | unicode
    """
    config = dict(
        user=source.config.username,
        password=source.config.password,
        server=source.config.host.encode('idna'),
        encoding=source.config.ftp_encoding,
        remote_path=folder.source_path,
        local_path=folder.target_path,
        exclude=folder.path_excludes,
        use_ftps=source.ftp.is_ftps,
        ignore_passive_mode_server_ip=source.ftp.ignore_passive_mode_server_ip
    )

    config_json = json.dumps(config, indent=4)
    log_config_json = json.dumps(clean_dict_args_for_log(config), indent=4)

    logger.fdebug(messages.FTP_COPY_CONFIG, config=log_config_json)

    return config_json


def parse_output(stdout, stderr):
    """
    :type stdout: str | unicode
    :type stderr: str | unicode
    :raises: parallels.plesk.source.web.utils.site_migration_exception.SiteMigrationError
    :rtype: list[parallels.core.reports.model.issue.Issue] | None
    """
    issues = []

    try:
        ftp_migrator_stdout = json.loads(stdout)
    except Exception as e:
        logger.exception()
        raise SiteMigrationError(
            messages.FTP_MIGRATOR_INVALID_OUTPUT,
            details=safe_format(
                messages.FTP_MIGRATOR_INVALID_OUTPUT_DETAILS,
                exception=e, stdout=stdout, stderr=stderr
            )
        )

    for ftp_migrator_issue in safe_get_list(ftp_migrator_stdout, 'issues'):
        issues.append(Issue(
            'ftp-migrator-issues', Issue.SEVERITY_ERROR,
            problem_text=ftp_migrator_issue.get('problem_text'),
            details_text=ftp_migrator_issue.get('details_text')
        ))

    return issues
