#!/usr/bin/python

# -*- coding: utf-8 -*-

from optparse import OptionParser
import urllib2, urllib
import codecs
import os, sys
import time

class Request():
    "Represents a single request to the yUML web service."
    opts = None
    body = u""
    out = None

    API_BASE = u"http://yuml.me/diagram"

    def log(self, msg):
        "Optionally log an informative message."
        if self.opts.v:
            print u"[yuml]", msg

    def loadbody(self):
        "Load the yUML text from stdin or a file."
        f = self.opts.infile
        self.log(u'Reading from %s' % ('stdin' if f == '-' else f))
        if f == '-':
            self.body = [x.decode('utf8') for x in sys.stdin.readlines()]
        elif os.path.exists(f):
            self.body = [x.strip() for x in codecs.open(f, 'r', 'utf-8').readlines() if x.strip()]
        else:
            raise IOError(u"File %s not found" % f)
        self.log(u'Done reading.')

    def prepout(self):
        "Open the output file."
        if self.opts.outfile:
            self.out = open(self.opts.outfile, 'wb')
        else:
            print "Usage: yuml [-i FILE] -o FILE"
            sys.exit(1)

    def run(self):
        "Execute the request."
        start = time.time()

        if not self.out:
            self.prepout()

        if not self.body:
            self.loadbody()            
            
        style = self.opts.style
        if style == 'boring':
            style = 'nofunky;'
        
        opts = style + (";scale:" + str(self.opts.scale) if self.opts.scale else '') + (";dir:" + str(self.opts.dir) if self.opts.dir else '')
        url = u"%s/%s/%s/" % (self.API_BASE, opts, self.opts.type)
        data = {'dsl_text' : u', '.join(self.body).encode('utf8') + '.' + self.opts.fmt}
        values = urllib.urlencode(data)
        headers = {
            'User-Agent' : 'wandernauta/yuml v0.1',
            'Content-Type' : 'application/x-www-form-urlencoded; charset=UTF-8'
        }

        self.log('Data: %s' % values)
        self.log('Requesting %s' % url)

        try:
            req = urllib2.Request(url, values, headers)
            img_name = urllib2.urlopen(req).read()

            self.log('Got image name %s' % img_name)

            img_arr = img_name.partition('.')
            img_url = url + img_arr[0] + '.' + self.opts.fmt

            self.log('Requesting %s' % img_url)

            req = urllib2.Request(img_url, None, headers)
            response = urllib2.urlopen(req).read()
        except urllib2.HTTPError, e:
            if e.code == 500:
                print "[yuml] Service returned 500: probably malformed input."
                sys.exit(1)
            else:
                raise

        self.out.write(response)
        self.log('Done after %f seconds' % (time.time() - start))

if __name__ == '__main__':
    op = OptionParser(usage="%prog [-i FILE] -o FILE", version="%prog 0.1")
    op.add_option("-i", "--in", dest="infile", help="read yuml from FILE instead of stdin", metavar="FILE", default="-")
    op.add_option("-o", "--out", dest="outfile", help="store output in FILE", metavar="FILE")
    op.add_option("-f", "--format", dest="fmt", help="use format FMT", metavar="FMT", default="png", choices=['png', 'pdf', 'jpg', 'svg'])
    op.add_option("-t", "--type", dest="type", help="draw a TYPE diagram", metavar="TYPE", default="class", choices=['class', 'activity', 'usecase'])
    op.add_option("-s", "--style", dest="style", help="use style STY", metavar="STY", default="scruffy", choices=['scruffy', 'boring', 'plain'])
    op.add_option("--scale", dest="scale", help="scale output to percentage", metavar="PERCENT", type="int")
    op.add_option("--dir", dest="dir", help="direction of the diagram LR RL TD", metavar="DIRECTION")
    op.add_option("-v", "--verbose", dest="v", help="print some debug info", action="store_true", default=False)

    (options, args) = op.parse_args()

    r = Request()
    r.opts = options
    r.run()
