#!/usr/bin/env python

# Quadrant -- An exceedingly simplistic console App.net client.
# Copyright (C) 2012  Nicholas Knight
# 
# 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 argparse
import shlex
import sys

w = sys.stdout.write

class _NoExitParser(argparse.ArgumentParser):
    def exit(self, status=0, message=None, *args, **kwargs):
        #print ("NEP:", status, message)
        pass

class Commander(object):
    def __init__(self, adn, t, interactive=True):
        self.t = t
        self.adn = adn
        
        if interactive:
            self.parser = _NoExitParser()
        else:
            self.parser = argparse.ArgumentParser()
        sp = self.parser.add_subparsers()

        p_quit = sp.add_parser('quit')
        p_quit.set_defaults(func=self.quit)

        p_rg = sp.add_parser('rg', help="Retrieve current global stream")
        p_rg.set_defaults(func=self.rg)

        p_post = sp.add_parser('post', help="Make a post")
        p_post.add_argument('text')
        p_post.set_defaults(func=self.post)

        p_auth = sp.add_parser('auth', help="Print URL to be used for authentication")
        p_auth.set_defaults(func=self.auth)

        p_settoken = sp.add_parser('settoken', help="Set access token")
        p_settoken.add_argument('token')
        p_settoken.set_defaults(func=self.settoken)

        p_whois = sp.add_parser('whois', help="Show information about user")
        p_whois.add_argument('username')
        p_whois.set_defaults(func=self.whois)

        p_getpost = sp.add_parser('getpost', help="Show a specific post")
        p_getpost.add_argument('post_id')
        p_getpost.set_defaults(func=self.getpost)

        p_gup = sp.add_parser('gup', help="Get latest posts by user")
        p_gup.add_argument('username')
        p_gup.set_defaults(func=self.get_user_posts)

        p_help = sp.add_parser('help', help="Display help")
        p_help.set_defaults(func=self.qhelp)
        
        p_get_thread = sp.add_parser('get_thread', help="Get thread of posts")
        p_get_thread.add_argument('post_id')
        p_get_thread.set_defaults(func=self.get_thread)
    
    def execute_args(self, argv):
        try:
            args = self.parser.parse_args(argv)
            f = args.func
            del args.func
            f(**args.__dict__)
        except Exception as e:
            print e
            pass
    
    def execute_line(self, line):
        tokens = shlex.split(line)
        print (tokens)
        self.execute_args(tokens)
        
    
    def print_user(self, user):
        print("{un} -- {n} -- {dt}".format(un=user.username, n=user.name, dt=user.description.text))
        
        state = []
        if user.follows_you: state.append("This user is following you")
        if user.you_follow: state.append("You are following this user")
        if user.you_muted: state.append("You have muted this user")
        
        print (' -- '.join(state))

    def print_post(self, post):
        print ("--------------------")
        if not post.user:
            w( self.t.bold("<"+self.t.underline("DELETED_USER?")+"> ") )
        else:
            w( self.t.bold("<{u}>".format(u=post.user.username)) )
    
        if post.is_deleted:
            w( self.t.underline("POST_DELETED") )
        else:
            w( post.text.rstrip() )
        w('\n')
        w( self.t.underline("id:")+str(post.post_id) + " " + self.t.underline("time:")+post.created_at )
        if post.reply_to:
            w( " "+self.t.underline("in reply to:") + " " + str(post.reply_to))
        w('\n')

    def quit(self):
        sys.exit(0)

    def rg(self):
        posts = self.adn.get_global_stream()
        for post in reversed(posts):
            self.print_post(post)

    def getpost(self, post_id):
        post = self.adn.get_post(post_id)
        self.print_post(post)

    def get_user_posts(self, username):
        posts = self.adn.get_user_posts(username)
        for post in reversed(posts):
            self.print_post(post)

    def whois(self, username):
        user = self.adn.get_user(username)
        self.print_user(user)

    def settoken(self, token):
        self.adn.settoken(token)

    def post(self, text):
        print ('{t.bold}Trying to post: {t.normal}{line}'.format(t=self.t, line=text))
        res = self.adn.post(text)
        self.print_post(res)

    def auth(self):
        url = "https://alpha.app.net/oauth/authenticate?client_id={cid}&response_type=token&scope=stream,write_post,follow,messages".format(cid="CWhqabzWV2WzCxvT2rVd7T668LrEyVAw")
        print (url)
    
    def get_thread(self, post_id):
        posts = self.adn.get_thread(post_id)
        for post in reversed(posts): self.print_post(post)
    
    def qhelp(self):
        self.parser.print_help()
