# This file is part of fedimg.
# Copyright (C) 2014-2017 Red Hat, Inc.
#
# fedimg is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# fedimg 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
# Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public
# License along with fedimg; if not, see http://www.gnu.org/licenses,
# or write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
#
# Authors:  David Gay <dgay@redhat.com>
#           Ralph Bean <rbean@redhat.com>
#           Sayan Chowdhury <sayanchowdhury@fedoraproject.org>

"""
Utility functions for fedimg.
"""

import functools
import socket
import subprocess

import paramiko
from libcloud.compute.types import Provider
from libcloud.compute.providers import get_driver

import fedimg


def get_file_arch(file_name):
    """ Takes a file name (probably of a .raw.xz image file) and returns
    the suspected architecture of the contained image. If it doesn't look
    like a 32-bit or 64-bit image, None is returned. """
    if file_name.find('x86_64') != -1:
        return 'x86_64'
    else:
        return None

def get_rawxz_urls(location, images):
    """ Iterates through all the images metadata and returns the url of .raw.xz
    files.
    """
    rawxz_list = [f['path'] for f in images if f['path'].endswith('.raw.xz')]
    if not rawxz_list:
        return []

    return map((lambda path: '{}/{}'.format(location, path)), rawxz_list)


def get_virt_types_from_url(url):
    """ Takes a URL to a .raw.xz image file) and returns the suspected
        virtualization type that the image file should be registered as. """
    file_name = url.split('/')[-1].lower()
    if file_name.find('atomic') != -1:
        # hvm is required for atomic images
        return ['hvm']
    else:
        # otherwise, build the AMIs with both virtualization types
        return ['hvm', 'paravirtual']


def region_to_driver(region):
    """ Takes a region name (ex. 'eu-west-1') and returns
    the appropriate libcloud provider value. """
    cls = get_driver(Provider.EC2)
    return functools.partial(cls, region=region)


def ssh_connection_works(username, ip, keypath):
    """ Returns True if an SSH connection can me made to `username`@`ip`. """
    ssh = paramiko.SSHClient()
    ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
    works = False
    try:
        ssh.connect(ip, username=username,
                    key_filename=keypath)
        works = True
    except (paramiko.BadHostKeyException,
            paramiko.AuthenticationException,
            paramiko.SSHException, socket.error) as e:
        pass
    ssh.close()
    return works


def safeget(dct, *keys):
    for key in keys:
        try:
            dct = dct[key]
        except KeyError:
            return None
    return dct

def external_run_command(command):
    raise NotImplementedError


def get_item_from_regex(regex, output):
    raise NotImplementedError


def get_source_for_image(image_url):
    raise NotImplementedError

@@ -995,16 +995,65 @@
 img.%0A%22%22%22
+%0Aimport logging%0Alog = logging.getLogger(%22fedmsg%22)
 %0A%0Aimport
@@ -1094,16 +1094,32 @@
 bprocess
+%0Aimport tempfile
 %0A%0Aimport
@@ -1172,16 +1172,16 @@
 rovider%0A
+
 from lib
@@ -1227,23 +1227,8 @@
 er%0A%0A
-import fedimg%0A%0A
 %0Adef
@@ -1552,16 +1552,17 @@
 n None%0A%0A
+%0A
 def get_
@@ -3050,13 +3050,8 @@
 ror)
- as e
 :%0A  
@@ -3247,16 +3247,17 @@
 rn dct%0A%0A
+%0A
 def exte
@@ -3292,169 +3292,594 @@
    r
-aise NotImplementedError%0A%0A%0Adef get_item_from_regex(regex, output):%0A    raise NotImplementedError%0A%0A%0Adef get_source_for_image(image_url):%0A    raise NotImplementedE
+et = subprocess.Popen(command, shell=True, stdin=subprocess.PIPE,%0A                           stdout=subprocess.PIPE, stderr=subprocess.PIPE,%0A                           close_fds=True)%0A    out, err = ret.communicate()%0A    return out, err%0A%0A%0Adef get_item_from_regex(regex, output):%0A    raise NotImplementedError%0A%0A%0Adef get_source_for_image(image_url):%0A    tmpdir = tempfile.mkdtemp()%0A    log.info(%22 Preparing temporary directory for download: %25r%22 %25 tmpdir)%0A    output, error = external_run_command(%0A        'wget',%0A        image_url,%0A        '-P',%0A        tmpdir%0A    )%0A%0A    return output, e
 rror

Implement the methods `external_run_command` & `get_source_from_image`