#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import io
import requests

from urllib.parse import urljoin

def hastebinit(data, ext='', raw=False, url='http://hastebin.com/'):

    r = requests.post(urljoin(url, 'documents'), data=data)
    response = r.json()

    key = response.get('key')
    if key is None:
        raise RuntimeError(response.get('message', "Unable to add document."))

    if raw: url = urljoin(url, 'raw/')
    return urljoin(url, key) + ext

if __name__ == '__main__':

    import os
    import sys
    import argparse
    import subprocess
    from functools import partial

    parser = argparse.ArgumentParser(
        description="""
This is a client for http://hastebin.com/ . It can paste a file
or data from stdin or take input from X's active selection and
output the url back to the active selection, this is particularly
useful for keybindings.
""",
        formatter_class=partial(argparse.HelpFormatter, max_help_position=30))


    parser.add_argument('-i', '--xclip-input', action='store_true',
                        help="get input data from x selection")
    parser.add_argument('-o', '--xclip-output', action='store_true',
                        help="set ouput data in x selection")
    parser.add_argument('-r', '--raw', action='store_true',
                        help="output the url to the raw paste")
    parser.add_argument('-n', '--name', nargs='?', const='',
                        help="override the filename/extension")
    parser.add_argument('-u', '--url', default='http://hastebin.com/',
                        help="url of the hastebin server to use")
    parser.add_argument('file', type=argparse.FileType('rb'),
                        nargs='*', default=[])
    args = parser.parse_args()

    if args.name is None:
        args.name = args.file[0].name if args.file else ""
    _, ext = os.path.splitext(args.name)

    # This is hack because hastebin doesn't handle some extensions well.
    if ext == ".c":
        ext = ".cpp#.c"

    if args.xclip_input:
        xclip = io.BytesIO(subprocess.check_output(["xclip", "-out"]))
        args.file.append(xclip)
    elif not args.file:
        args.file = [sys.stdin.buffer]

    if args.xclip_output:
        # Set empty selection before doing remote requests.
        # otherwise trying to past will paste garbage while
        # the key hasn't been received which is a problem on
        # slow connections.
        p = subprocess.Popen(['xclip', '-in'], stdin=subprocess.PIPE)
        p.communicate(input=b"")

    urls = []

    for f in args.file:
        try:
            urls.append(hastebinit(f.read(), ext, raw=args.raw, url=args.url))
        except RuntimeError as e:
            print(e)

    if not urls:
        exit(1)

    if args.xclip_output:
        p = subprocess.Popen(['xclip', '-in'], stdin=subprocess.PIPE)
        p.communicate(input=bytes(", ".join(urls), 'utf8'))

    for url in urls:
        print(url)

