# -*- coding: utf-8 -*-
import base64
import os
import re
import gzip
import tarfile
from gluon.contrib.simplejsonrpc import ServerProxy
from gluon._compat import StringIO, ProtocolError, urlencode, urllib2

def deploy():
    response.title = T('Deploy to pythonanywhere')
    return {}


def create_account():
    """ Create a PythonAnywhere account """
    if not request.vars:
        raise HTTP(400)
    
    if request.vars.username and request.vars.web2py_admin_password:
        # Check if web2py is already there otherwise we get an error 500 too.
        client = ServerProxy('https://%(username)s:%(web2py_admin_password)s@%(username)s.pythonanywhere.com/admin/webservices/call/jsonrpc' % request.vars)
        try:
            if client.login() is True:
                return response.json({'status': 'ok'})
        except ProtocolError as error:
            pass

    url = 'https://www.pythonanywhere.com/api/web2py/create_account'
    data = urlencode(request.vars)
    req = urllib2.Request(url, data)
    
    try:
        reply = urllib2.urlopen(req)
    except urllib2.HTTPError as error:
        if error.code == 400:
            reply = error
        elif error.code == 500:
            return response.json({'status':'error', 'errors':{'username': ['An App other than web2py is installed in the domain %(username)s.pythonanywhere.com' % request.vars]}})
        else:
            raise
    response.headers['Content-Type'] = 'application/json'
    return reply.read()


def list_apps():
    """ Get a list of apps both remote and local """
    if not request.vars.username or not request.vars.password:
        raise HTTP(400)
    client = ServerProxy('https://%(username)s:%(password)s@%(username)s.pythonanywhere.com/admin/webservices/call/jsonrpc' % request.vars)
    regex = re.compile('^\w+$')
    local = [f for f in os.listdir(apath(r=request)) if regex.match(f)]
    try:
        pythonanywhere = client.list_apps()
    except ProtocolError as error:
        raise HTTP(error.errcode)
    return response.json({'local': local, 'pythonanywhere': pythonanywhere})


def bulk_install():
    """ Install a list of apps """

    def b64pack(app):
        """
        Given an app's name, return the base64 representation of its packed version.
        """
        folder = apath(app, r=request)
        tmpfile = StringIO()
        tar = tarfile.TarFile(fileobj=tmpfile, mode='w')
        try:
            filenames = listdir(folder, '^[\w\.\-]+$', add_dirs=True, 
                                exclude_content_from=['cache', 'sessions', 'errors'])
            for fname in filenames:
                tar.add(os.path.join(folder, fname), fname, False)
        finally:
            tar.close()
        tmpfile.seek(0)
        gzfile = StringIO()
        w2pfp = gzip.GzipFile(fileobj=gzfile, mode='wb')
        w2pfp.write(tmpfile.read())
        w2pfp.close()
        gzfile.seek(0)
        return base64.b64encode(gzfile.read())

    request.vars.apps = request.vars['apps[]']
    if not request.vars.apps or not request.vars.username or not request.vars.password:
        raise HTTP(400)
    if not isinstance(request.vars.apps, list):
        request.vars.apps = [request.vars.apps]  # Only one app selected

    client = ServerProxy('https://%(username)s:%(password)s@%(username)s.pythonanywhere.com/admin/webservices/call/jsonrpc' % request.vars)

    for app in request.vars.apps:
        try:
            client.install(app, app+'.w2p', b64pack(app))
        except ProtocolError as error:
            raise HTTP(error.errcode)

    return response.json({'status': 'ok'}) 
