""" surl.services """

#    This program is free software: you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation, either version 3 of the License, or
#    (at your option) any later version.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU General Public License for more details.
#
#    You should have received a copy of the GNU General Public License
#    along with this program.  If not, see <http://www.gnu.org/licenses/>.

import xml.dom.minidom
import re
import sys
try:
    import json
except ImportError:
    try:
        import simplejson as json
    except ImportError:
        sys.stderr.write("Warning: json module could not load\n")

from surl import core

def supportedServices():
    """ Returns a dictionary with the supported surl services """
    dict_service = {
        'bit.ly'       : bitly_com('bit.ly'),
        'bitly.com'    : bitly_com('bit.ly'),
        'j.mp'         : bitly_com('j.mp'),
        'chilp.it'     : chilp_it(),
        'clck.ru'      : clck_ru(),
        'crum.bs'      : crum_bs(),
        'decenturl.com': decenturl_com(),
        'goo.gl'       : goo_gl(),
        'is.gd'        : is_gd(),
        'liip.to'      : liip_to(),
        'metamark.net' : metamark_net(),
        'redir.ec'     : redir_ec(),
        'ri.ms'        : tinyarro_ws('ri.ms'),
        'ta.gd'        : tinyarro_ws('ta.gd'),
        'tinyarro.ws'  : tinyarro_ws('tinyarro.ws'),
        'sn.im'        : sn_im('sn.im'),
        'snipr.com'    : sn_im('snipr.com'),
        'snipurl.com'  : sn_im('snipurl.com'),
        'snurl.com'    : sn_im('snurl.com'),
        'tiny.cc'      : tiny_cc(),
        'tinyurl.com'  : tinyurl_com(),
        'turl.ca'      : turl_ca(),
        'twurl.nl'     : twurl_nl(),
        'urlx.ru'      : urlx_ru(),
    }
    return dict_service

class Service(object):
    requires_auth = False

class tinyurl_com(Service):
    #http://tinyurl.com/api-create.php?url=http://example.com/
    #GET or POST
    #Notes: Soon custom alias (title)
    def get(self, args, url):
        values = {
            'url': url,
        }
        service_link = "http://tinyurl.com/api-create.php"
        result = core().getShortenedLink(service_link, url, values)
        return result

class bitly_com(Service):
    #curl "http://api.bit.ly/v3/shorten&longUrl=http://www.google.com&format=json&login=bitlyapidemo&apiKey=R_0da49e0a9118ff35f52f629d2d71bf07"
    #GET
    #TODO: Check for custom alias title
    #Needs API and username
    def parseJSON(self, json_string):
        array = json.loads(json_string)
        #print(array)
        try:
            shorturl = array['data']['url']
        except KeyError:
            #no shortUrl: errorCode > 0, no http://* or new API?
            return self.url

        if array['status_txt'] == 'OK' and array['status_code'] == 200:
            result = shorturl
        else:
            result = self.url

        return result

    def __init__(self, service_domain):
        self.service_link = 'http://api.bitly.com/v3/shorten?domain=' + service_domain

    def get(self, args, url):
        if not "://" in url:
            #Assume http://
            url = "http://" + url
        self.url = url
        try:
            u = args['username']
            a = args['api-key']
        except KeyError: # For use from other Python apps
            u = a = ''

        if u == '' or a == '':
            u = 'bitlyapidemo'
            a = 'R_0da49e0a9118ff35f52f629d2d71bf07'
        sl = self.service_link + "&login=%s&apiKey=%s&longUrl=%s&format=json"
        result = core().getShortenedLink(sl % (u, a, url), url)
        print(result)
        if not result == url:
            # If there was no error
            # {{ "status_code": 200, "status_txt": "OK", "data": { "long_url": "http:\/\/www.google.com\/", "url": "http:\/\/bit.ly\/fj4ZC", "hash": "fj4ZC", "global_hash": "2V6CFi", "new_hash": 0 } } }
            result2 = self.parseJSON(result)
        else:
            result2 = url
        return result2

class chilp_it(Service):
    #http://chilp.it/api.php?url=http://www.example.com
    #GET
    def get(self, args, url):
        service_link = "http://chilp.it/api.php?url=%s"
        result = core().getShortenedLink(service_link % url, url)
        return result

class clck_ru(Service):
    #http://clck.ru/--?url=http://myfreeweb.ru
    def get(self, args, url):
        service_link = "http://clck.ru/--?url=%s"
        result = core().getShortenedLink(service_link % url, url)
        return result

class crum_bs(Service):
    #http://crum.bs/api.php?function=simpleshorten&url=http://example.com
    def get(self, args, url):
        service_link = "http://crum.bs/api.php?function=simpleshorten&url=%s"
        result = core().getShortenedLink(service_link % url, url)
        return result

class sn_im(Service):
    #http://snipr.com/site/getsnip?sniplink=http://www.example.com&snipformat=simple&snipuser=someuser&snipapi=someapi&snipnick=sometitle
    #http://support.snipurl.com/faq/is-there-a-sniprsnipurl-api
    #POST
    requires_auth = True
    def __init__(self, service_domain):
        self.service_link = 'http://' + service_domain + '/site/getsnip'

    def get(self, args, url):
        if not args['api-key'] or not args['username']:
            #print("ERROR: Service requires username and api key")
            return url
        values = {
            'sniplink'  : url,
            'snipformat': 'simple',
            'snipapi'   : args['api-key'],
            'snipuser'  : args['username'],
            'snipnick'  : args['title'],
        }
        print(values)
        result = core().getShortenedLink(self.service_link, url, values)
        return result

class decenturl_com(Service):
    #curl "http://decenturl.com/api-get?u=youtube.com%2Fwatch%3Fv%3DpQHX-SjgQvQ&t=medieval&k=apikey"
    #GET
    #http://decenturl.com/tools
    #Note: Needs API key
    #TODO: Did not check new format with API
    def parseJSON(self, json_string):
        array = json.loads(json_string)
        #print(array)
        if array[0] == "ok":
            result = array[3]
        else:
            result = self.url
        return result

    def get(self, args, url):
        self.url = url
        k = args["api-key"]
        if not k:
            return url
        t = args["title"]
        service_link = "http://decenturl.com/api-get?u=%s&t=%s&k=%s"
        url_response = core().getShortenedLink(service_link % (url, t, k), url)
        if not url_response == url:
            # If there was no error
            # Response example: ["ok", "example/example-web-page-2", "http://example.com/", "http://example.decenturl.com/example-web-page-2"]
            result = self.parseJSON(url_response)
        else:
            result = url
        return result

class goo_gl(Service):
    #curl -S "http://goo.gl/api/url" -d "url=http://www.google.com"
    #Not documented in https://www.googleapis.com/urlshortener/v1/url
    #POST
    def parseJSON(self, json_string):
        jdict = json.loads(json_string)
        if jdict.has_key('error'):
            result = self.url
        elif jdict.has_key('short_url'):
            result = jdict['short_url']
        return result

    def get(self, args, url):
        self.url = url
        service_link = 'http://goo.gl/api/url'
        values = { "url": url }
        url_response = core().getShortenedLink(service_link, url, values)
        if not url_response == url:
            result = self.parseJSON(url_response)
        else:
            result = url
        return result

class is_gd(Service):
    #http://is.gd/api.php?longurl=http://www.example.com
    #GET
    #http://is.gd/api_info.php
    def get(self, args, url):
        service_link = "http://is.gd/api.php?longurl=%s"
        # hack over it, don't use POST
        result = core().getShortenedLink(service_link % url, url)
        return result

class liip_to(Service):
    #curl "http://liip.to/api/txt/?url=http://google.com&code="
    #GET
    def get(self, args, url):
        service_link = "http://liip.to/api/txt/?url=%s&code=%s"
        custom = args['title']
        result = core().getShortenedLink(service_link % (url, custom), url)
        return result

class redir_ec(Service):
    #http://redir.ec/_api/rest/redirec/create?url=http://www.example.com
    #GET
    #TODO: implement redirec, appid, and apikey (http://redir.ec/_api)
    def get(self, args, url):
        service_link = "http://redir.ec/_api/rest/redirec/create?url=%s"
        result = core().getShortenedLink(service_link % url, url)
        if result == "please provide a longer url":
          return url
        else:
          return result

class tinyarro_ws(Service):
    #http://tinyarro_ws/api-create.php?url=http://www.example.com
    #http://tinyarrows.com/info/api
    #GET
    def __init__(self, service_domain):
        self.service_domain = service_domain
        self.service_link = 'http://' + service_domain
    def get(self, args, url):
        title = args['title']
        if title:
            req = "/api-create.php?utfpure=1&host=%s&url=%s&suggest=" + title
        else:
            req = "/api-create.php?utfpure=1&host=%s&url=%s"
        service_link = self.service_link+req
        result = core().getShortenedLink(service_link % (self.service_domain,url), url)
        return result

class metamark_net(Service):
    #curl "http://metamark.net/api/rest/simple?long_url=http://www.google.com"
    #GET
    def get(self, args, url):
        service_link = "http://metamark.net/api/rest/simple?long_url=%s"
        result = core().getShortenedLink(service_link % (url), url)
        return result

class turl_ca(Service):
    #curl -S "http://turl.ca/api.php?url=http://www.google.com&tag=moofoocoo"
    #GET

    def errorcheck(self, tstring):
        reply = tstring.split(":")
        if reply[0] == "SUCCESS":
            result = "http://turl.ca/" + reply[1]
        elif reply[0] == "ERROR":
            result = self.url
        return result

    def get(self, args, url):
        self.url = url
        tag = args['title']
        service_link = "http://turl.ca/api.php?url=%s&tag=%s"
        result = core().getShortenedLink(service_link % (url, tag), url)
        result2 = self.errorcheck(result)
        return result2

class twurl_nl(Service):
    #curl "http://tweetburner.com/links" --data "link[url]=the_url_to_twurl"
    #POST
    def get(self, args, url):
        values = {
            'link[url]': url,
        }
        service_link = "http://tweetburner.com/links"
        result = core().getShortenedLink(service_link, url, values)
        return result

class urlx_ru(Service):
    #curl -S "http://urlx.ru/api/http://example.com"
    #GET
    
    def get(self, args, url):
        service_link = 'http://urlx.ru/api/' + url
        values = {}
        result = core().getShortenedLink(service_link, url, values)
        return result


class tiny_cc(Service):
    #http://tiny.cc/?c=rest_api&m=shorten&version=2.0.3&format=json&shortUrl=yourtitle&longUrl=http://example.com&login=youruser&apiKey=yourapi
    #GET
    #{"errorCode":"0","errorMessage":"","results":{"short_url":"http:\/\/tiny.cc\/BJmf2b","userHash":"BJmf2b","hash":"BJmf2b"},"statusCode":"OK"}
    #{"errorCode":1215,"errorMessage":"Short URL is not correct or existed.","results":"","statusCode":"ERROR"}
    #Note: needs http://
    def parseJSON(self, json_string):
        jdict = json.loads(json_string)
        if not jdict["statusCode"] == "OK":
            result = self.url
        else:
            result = jdict['results']['short_url']
        return result
    def get(self, args, url):
        if not args['api-key'] or not args['username']:
            # Needs API
            return url
        if not "://" in url:
            #Assume http://
            url = "http://" + url
        self.url = url
        u = args['username']
        a = args['api-key']
        t = args['title']
        print(url)
        values = {}
        service_link = "http://tiny.cc/"
        req = "?c=rest_api&m=shorten&version=2.0.3&format=json\
&shortUrl=%s&longUrl=%s&login=%s&apiKey=%s" % (t, url, u, a)
        print(service_link + req)
        result = core().getShortenedLink(service_link + req, url, values)
        result2 = self.parseJSON(result)
        return result2
