#  Copyright 2014 Rackspace, Inc.
#
#  Licensed under the Apache License, Version 2.0 (the "License");
#  you may not use this file except in compliance with the License.
#  You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
#  Unless required by applicable law or agreed to in writing, software
#  distributed under the License is distributed on an "AS IS" BASIS,
#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#  See the License for the specific language governing permissions and
#  limitations under the License.

import json
import requests

"""Small Swift client library."""


class SwiftClient(object):

    def __init__(self, auth_url, tenant, username, password):
        self._auth_url = auth_url
        self._tenant = tenant
        self._username = username
        self._password = password

        self._token = None
        self._swift_url = None

    def auth(self):
        headers = {'Content-Type': 'application/json',
                   'Accept': 'application/json'}
        payload = {'auth':
                   {'tenantName': self._tenant,
                    'passwordCredentials':
                    {'username': self._username, 'password': self._password}}}
        r = requests.post(self._auth_url + '/tokens',
                          data=json.dumps(payload),
                          headers=headers)
        data = r.json()

        self._token = data['access']['token']['id']
        print('found token: %s...' % self._token[:20])

        for service in data['access']['serviceCatalog']:
            if service['name'] == 'swift':
                self._swift_url = service['endpoints'][0]['publicURL']
                # Force hostname to be localhost -- for testing with a
                # SSH tunnel when Swift cannot be reached directly.
                # p = list(urlparse.urlparse(self._swift_url))
                # parts = list(p)
                # parts[1] = 'localhost:%d' % p.port
                # self._swift_url = urlparse.urlunparse(parts)
                print('found Swift: %s' % self._swift_url)

    def upload(self, path, data):
        headers = {'X-Auth-Token': self._token}
        r = requests.put('%s/%s' % (self._swift_url, path),
                         data=data, headers=headers)
        if r.status_code == 200:
            print('created %s succesfully' % path)
        elif r.status_code == 201:
            print('updated %s succesfully' % path)
        else:
            raise RuntimeError('uploading %s failed with status %d'
                               % (path, r.status_code))


class ZwiftClient(SwiftClient):

    def post_job(self, job):
        headers = {'X-Auth-Token': self._token,
                   'Accept': 'application/json',
                   'X-Zerovm-Execute': '1.0',
                   'Content-Type': 'application/json'}
        r = requests.post(self._swift_url, data=job, headers=headers)
        print(r)
        print(r.content)

@@ -674,16 +674,689 @@
 object):
+%0A    %22%22%22%0A    Lightweight Swift client. Supports authentication to Keystone and basic%0A    Swift functions.%0A%0A    :param auth_url:%0A        Keystone authorization URL, akin to %60--os-auth-url%60 / %60OS_AUTH_URL%60.%0A%0A        The URL against which we can perform Swift operations is retrieved from%0A        the Keystone service catalog, which is obtained when we authenticate to%0A        this %60auth_url%60.%0A    :param tenant:%0A        Keystone tenant name, akin to %60--os-tenant-name%60 / %60OS_TENANT_NAME%60).%0A    :param username:%0A        Keystone username, akin to %60--os-username%60 / %60OS_USERNAME%60.%0A    :param password:%0A        Keystone password, akin to %60--os-password%60 / %60OS_PASSWORD%60.%0A    %22%22%22
 %0A%0A    de
@@ -1623,16 +1623,241 @@
 (self):%0A
+        %22%22%22%0A        Connect to the Keystone service and cache the access token and Swift%0A        endpoint URL (if available in the service catalog).%0A%0A        Calling this is a prequisite for any Swift operations.%0A        %22%22%22%0A
         
@@ -3048,16 +3048,295 @@
  data):%0A
+        %22%22%22%0A        Upload file contents in %60data%60 to the %60path%60 in Swift.%0A%0A        :param path:%0A            %3Ccontainer%3E/%3Cfilename%3E in Swift where we want to upload the given%0A            %60data%60.%0A        :param data:%0A            Contents of a file, as a string/bytes.%0A        %22%22%22%0A
         
@@ -3834,37 +3834,408 @@
 t):%0A
-%0A    def post_job(self, job):
+    %22%22%22%0A    Extends :class:%60SwiftClient%60 to add ZeroVM/zar execution functionality.%0A    %22%22%22%0A%0A    def post_job(self, job):%0A        %22%22%22%0A        Start a ZeroVM job, using a pre-uploaded zar.%0A%0A        :param str job:%0A            JSON string containing the job/servlet configuration. For more%0A            info, see:%0A            https://github.com/zerovm/zerocloud/blob/icehouse/doc/Servlets.md%0A        %22%22%22
 %0A   

add docs to SwiftClient/ZwiftClient