from pyramid.response import Response
from pyramid.httpexceptions import (
    HTTPFound,
    HTTPNotFound,
    )
from pyramid.renderers import get_renderer
from pyramid.security import (
    remember, 
    forget, 
    authenticated_userid,
    )
from pyramid.view import (
    view_config,
    forbidden_view_config,
    )
from pyramid.url import route_url

from repoze.timeago import get_elapsed
from datetime import datetime


from .security import check_login
from functools import reduce

from helper import User,Chirp

conn_err_msg = """\
Pyramid is having a problem using your SQL database.  The problem
might be caused by one of the following things:

1.  You may need to run the "initialize_birdie_db" script
    to initialize your database tables.  Check your virtual 
    environment's "bin" directory for this script and try to run it.

2.  Your database server may not be running.  Check that the
    database server referred to by the "sqlalchemy.url" setting in
    your "development.ini" file is running.

After you fix the problem, please restart the Pyramid application to
try it again.
"""

MAX_CHIRPS = 15
MAX_MY_CHIRPS = 5
MAX_USERS = 5
MAX_FRIENDS = 0
MAX_FOLLOWERS = 0

myUser = User()
myChirp = Chirp()

class BirdieViews(object):
    def __init__(self, request):
        self.request = request
        renderer = get_renderer("templates/layout-bootstrap.pt")
        self.layout = renderer.implementation().macros['layout']
        self.logged_in = authenticated_userid(request)
        self.app_url = request.application_url
        self.static_url = request.static_url

    @view_config(route_name='about',
                renderer='templates/about-bootstrap.pt')
    def about_page(self):
        return {}            
                
    @view_config(route_name='home',
                renderer='templates/birdie-bootstrap.pt')
    def birdie_view(self):
        
        username = self.logged_in
        user = None
        user_id = None
        chirps, users, user_friends= [], [], []
        
        if username: 
            #get friends
            user_id = myUser.getIDbyName(username)
            if user_id:
                user = myUser.getUserByID(user_id)
                user_friends = myUser.getFriends(user_id)
                if(user_friends):
                    friends = [myUser.getUserByID(user_friend) for user_friend in user_friends]
                
            #get all chrips   
            chirp_ids = myChirp.getAllChirps()
            if(chirp_ids):
                chirps = [myChirp.getChirpByID(chirp_id) for chirp_id in chirp_ids]
                
                if(chirps):
                    for chirp in chirps:
                        myChirp.addChirpAUsername(chirp)
                        myChirp.addChirpAFullname(chirp)
            
            #get all users
            users = myUser.getAllUsers()
        
        return {'elapsed': get_elapsed,
            'user': user,
            'user_id':user_id,
            'user_friends':user_friends,
            'chirps': chirps[:MAX_CHIRPS],
            'latest_users': users[:MAX_USERS],
            'users_count': len(users),
            'chirps_count': len(chirps),
        }


    @view_config(route_name='mybirdie',
                permission='registered',
                renderer='templates/mybirdie-bootstrap.pt')
    def my_birdie_view(self):
        
        username = self.logged_in
        chirps, my_chirps, friends, followers = [], [], [], []
        
        user_id = myUser.getIDbyName(username)
        
        if ('form.submitted' in self.request.params and self.request.params.get('chirp')):
            chirp = self.request.params.get('chirp')
            author = user_id
            timestamp = datetime.utcnow()
            
            myChirp.addChirp(chirp,timestamp,author)
            
            url = self.request.route_url('mybirdie', username=username)
            return HTTPFound(url)

#        chirps = reduce(lambda x, y: x.extend(y), [f.chirps for f in user.friends if f.chirps], [])
        if user_id:
            user = myUser.getUserByID(user_id)
            followers_ids = myUser.getFollowers(user_id)
            friends_ids = myUser.getFriends(user_id)
        else:
            user = None
            followers_ids, friends_ids = [], []
        
        if(friends_ids):
            friends = [myUser.getUserByID(friend_id) for friend_id in friends_ids]
            for f in friends_ids:
                chirps[len(chirps):] = [myChirp.getChirpByID(chirp_id) for chirp_id in myUser.getChirps(f)]
            if chirps:
                for chirp in chirps:
                    myChirp.addChirpAFullname(chirp)
                    myChirp.addChirpAUsername(chirp)
                
        if(followers_ids):
            followers = [myUser.getUserByID(follower_id) for follower_id in followers_ids]
        if user_id:
            user_chirps = myUser.getChirps(user_id)
            if user_chirps:
                my_chirps = [myChirp.getChirpByID(user_chirp) for user_chirp in user_chirps]
                if my_chirps:
                    for chirp in my_chirps:
                        myChirp.addChirpAUsername(chirp)
                        myChirp.addChirpAFullname(chirp)

        return {'elapsed': get_elapsed,
                'user': user,
                'user_friends':friends,
                'user_followers':followers,
                'chirps': chirps[:MAX_CHIRPS],
                'my_chirps': my_chirps[:MAX_MY_CHIRPS]}

    @view_config(route_name='login',
                renderer='templates/login-bootstrap.pt')
    @forbidden_view_config(renderer='birdie:templates/login-bootstrap.pt')
    def login(self):
        request = self.request
        login_url = request.route_url('login')
        join_url = request.route_url('join')
        came_from = request.params.get('came_from')
        if not came_from : # first time it enters the login page
            came_from = request.referer
        message = ''
        login = ''
        password = ''
        if 'form.submitted' in request.params:
            login = request.params['login']
            password = request.params['password']
            if check_login(login, password):
                headers = remember(request, login)
                if (came_from == login_url or came_from == join_url or came_from == self.app_url):
                    came_from = request.route_url('mybirdie', username=login)  # never use login form itself as came_from
                return HTTPFound(location=came_from,
                                 headers=headers)
            message = 'Failed login'

        return {'message': message,
                'came_from': came_from,
                'login': login,
                'password': password}
                

    @view_config(route_name='logout')
    def logout(self):
        headers = forget(self.request)
        url = self.request.route_url('home')
        return HTTPFound(location=url,
                         headers=headers)

    @view_config(route_name='join',
                renderer='birdie:templates/join-bootstrap.pt')
    def join(self):
        
        request = self.request
        join_url = request.route_url('join')
        login_url = request.route_url('login')
        came_from = request.params.get('came_from')
        if not came_from: # first time it enters the join page
            came_from = request.referer
        
        if 'form.submitted' in request.params:
        # registration form has been submitted
            username = request.params.get('username')
            password = request.params.get('password')
            confirm = request.params.get('confirm')
            fullname = request.params.get('fullname')
            about = request.params.get('about')
            message = ''
        
            user_id = myUser.getIDbyName(username)
            if(user_id):
                user = myUser.getUserByID(user_id)
            else:
                user = None
                
            if username is '':
                message = "The username is required."
            elif (password is '' and confirm is ''):
                message = "The password is required."
            elif user:
                message = "The username {} already exists.".format(username)
            elif confirm != password:
                message = "The passwords don't match."
            elif len(password) < 6:
                message = "The password is too short."

            if message:
                return {'message': message,
                        'came_from': came_from,
                        'username': username,
                        'fullname': fullname,
                        'about': about}
           
           # register new user
            dor = datetime.utcnow()
            
            myUser.addUser(user_id,username,password,fullname,about,dor.strftime('%m/%d/%Y'))
            
            headers = remember(request, username)
            
            if (came_from == join_url or came_from == login_url or came_from == self.app_url):
                came_from = request.route_url('mybirdie', username=username)  # never use login form itself as came_from
            return HTTPFound(location = came_from,
                             headers = headers)

        # default - prepare empty sign in form
        return {'message': '',
                'came_from': came_from,
                'username': '',
                'fullname': '',
                'about': ''}


    @view_config(route_name='profile',
                 permission='registered',
                 renderer='birdie:templates/user-bootstrap.pt')
    def profile_view(self):
        
        auth_username = self.logged_in
        username = self.request.matchdict['username']
        chirps = []
        ufcount = 0
        ufocount = 0
        if auth_username==username: # redirect to my_birdie page
            return HTTPFound(location = self.request.route_url('mybirdie', username=username))

        auth_user_id = myUser.getIDbyName(auth_username)
        if auth_user_id:
            auth_user = myUser.getUserByID(auth_user_id)
            auth_userfriends = myUser.getFriends(auth_user_id)
            
        user_id = myUser.getIDbyName(username)
        if user_id:
            user = myUser.getUserByID(user_id)
            chirps = [myChirp.getChirpByID(chirp_id) for chirp_id in myUser.getChirps(user_id)]
            
            ufcount = len(myUser.getFriends(user_id))
            ufocount = len(myUser.getFollowers(user_id))
        

        return {'elapsed': get_elapsed,
                'auth_user' : auth_user,
                'auth_userfriends':auth_userfriends,
                'user': user,
                'user_id':user_id,
                'ufcount':ufcount,
                'ufocount':ufocount,
                'chirps': chirps[:MAX_CHIRPS]}
                

    @view_config(route_name='follow',
                 permission="registered",
                 renderer='birdie:templates/fake.pt')
    def follow(self):
        username = self.logged_in
        came_from=self.request.referer
        if not came_from:
            came_from=self.app_url
        #get user
        user_id = myUser.getIDbyName(username)
        user_friends = []
        if user_id:
            user = myUser.getUserByID(user_id)
            user_friends = myUser.getFriends(user_id)

        #get friend
        friend_username = self.request.matchdict.get('username')
        friend_id = myUser.getIDbyName(friend_username)
        
        followers = []
        if friend_id:
            friend = myUser.getUserByID(friend_id)
            followers = myUser.getFollowers(friend_id)
        
        
        if (friend_id != user_id and friend_id not in user_friends):
            myUser.addFriend(user_id,friend_id)
        if(friend_id != user_id and user_id not in followers):
            myUser.addFollower(friend_id,user_id)
            
        
        return HTTPFound(location=came_from)


    @view_config(route_name='unfollow',
                 permission="registered",
                 renderer='birdie:templates/fake.pt')
    def unfollow(self):
        username = self.logged_in
        came_from=self.request.referer
        if not came_from:
            came_from=self.app_url
        
        user_id = myUser.getIDbyName(username)
        user_friends = []
        if user_id:
            user = myUser.getUserByID(user_id)
            user_friends = myUser.getFriends(user_id)
            
        friend_username = self.request.matchdict.get('username')
        friend_id = myUser.getIDbyName(friend_username)
        followers =[]
        if friend_id:
            friend = myUser.getUserByID(friend_id)
            followers = myUser.getFollowers(friend_id)
        
        if friend_id in user_friends:
            myUser.rmFriend(user_id,friend_id)
        if user_id in followers:
            myUser.rmFollower(friend_id,user_id)
            
        return HTTPFound(location=came_from)

