#!/usr/bin/python

#       Licensed to the Apache Software Foundation (ASF) under one
#       or more contributor license agreements.  See the NOTICE file
#       distributed with this work for additional information
#       regarding copyright ownership.  The ASF licenses this file
#       to you 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 types
from sys import stdout
import os
import urllib
from urllib2 import urlopen, HTTPError
from urlparse import urlparse, urljoin
from optparse import OptionParser
from ConfigParser import ConfigParser


def smart_str(s, encoding='utf-8', strings_only=False, errors='strict'):
    """
    Returns a bytestring version of 's', encoded as specified in 'encoding'.

    If strings_only is True, don't convert (some) non-string-like objects.

    This function was borrowed from Django
    """
    if strings_only and isinstance(s, (types.NoneType, int)):
        return s
    elif not isinstance(s, basestring):
        try:
            return str(s)
        except UnicodeEncodeError:
            if isinstance(s, Exception):
                # An Exception subclass containing non-ASCII data that doesn't
                # know how to print itself properly. We shouldn't raise a
                # further exception.
                return ' '.join([smart_str(arg, encoding, strings_only,
                                           errors) for arg in s])
            return unicode(s).encode(encoding, errors)
    elif isinstance(s, unicode):
        r = s.encode(encoding, errors)
        return r
    elif s and encoding != 'utf-8':
        return s.decode('utf-8', errors).encode(encoding, errors)
    else:
        return s


def generate_smart_str(params):
    for (key, value) in params:
        yield smart_str(key), smart_str(value)


def urlencode(params):
    """
    A version of Python's urllib.urlencode() function that can operate on
    unicode strings. The parameters are first case to UTF-8 encoded strings and
    then encoded as per normal.
    """
    return urllib.urlencode([i for i in generate_smart_str(params)])


class Signer(object):

    def __init__(self, token):
        self.token = token

    def __call__(self, path, params):
        if self.token is None:
            return params
        params.append(('token', self.token))
        return params


def main():
    usage = 'usage: %prog [options] [PageName [file]]'
    op = OptionParser(usage=usage)
    op.add_option('-c', '--config', metavar='CONFIG')
    op.add_option('-t', '--token', metavar='TOKEN')
    op.add_option('', '--anon', action='store_true')
    op.add_option('-u', '--url', metavar='URL')
    (options, args) = op.parse_args()

    pagename = None
    markdown = None
    method = 'GET'

    pagename_given = len(args) >= 1
    if pagename_given:
        pagename = args[0]

    filename_given = len(args) > 1
    if filename_given:
        method = 'PUT'
        f = open(args[1], 'r')
        markdown = f.read()

    config = ConfigParser()
    config.read(
        [str(os.path.expanduser('~/.forge-api.ini')), str(options.config)])

    token = None
    if not options.anon:
        token = options.token or config.get('keys', 'token')

    url = options.url or config.get('wiki', 'url')
    if pagename_given:
        url = urljoin(url, urllib.quote(pagename))
    print url

    sign = Signer(token)
    params = [('text', markdown)] if method == 'PUT' else []
    params = sign(urlparse(url).path, params)
    try:
        if method == 'PUT':
            result = urlopen(url, urlencode(params))
        else:
            result = urlopen(url + '?' + urlencode(params))
        stdout.write(result.read())
    except HTTPError, e:
        stdout.write(e.read())

if __name__ == '__main__':
    main()
