"""
Copyright 2016 Brian Quach
Licensed under MIT (https://github.com/brianquach/udacity-nano-fullstack-catalog/blob/master/LICENSE)  # noqa
"""
import httplib2
import json
import os
import random
import string
from apiclient import discovery
from apiclient import errors as gErrors
from dicttoxml import dicttoxml
from flask import flash
from flask import Flask
from flask import g
from flask import jsonify
from flask import make_response
from flask import Markup
from flask import redirect
from flask import render_template
from flask import request
from flask import session
from flask import url_for
from functools import wraps
from oauth2client import client
from oauth2client.file import Storage
from werkzeug import secure_filename
from catalog import app
from catalog import CLIENT_ID
from catalog import db
from catalog import G_CREDENTIAL_STORAGE
from catalog import UPLOAD_PATH
from catalog.forms import CreateCatalogItemForm
from catalog.forms import EditCatalogItemForm
from catalog.models import Catagory
from catalog.models import CatagoryItem
from catalog.models import User


def login_required(f):
    @wraps(f)
    def decorated_function(*args, **kwargs):
        if 'user_id' not in session:
            return redirect(url_for('dashboard'))
        return f(*args, **kwargs)
    return decorated_function


def owner_required(f):
    @wraps(f)
    def decorated_function(*args, **kwargs):
        catagory_item = CatagoryItem.\
            query.\
            filter_by(
                id=kwargs['catagory_item_id'],
                user_id=session['user_id']
            ).\
            first()
        if catagory_item is None:
            return redirect(
                url_for(
                    'view_catagory_item',
                    catagory_item_id=kwargs['catagory_item_id']
                )
            )
        return f(catagory_item)
    return decorated_function


@app.context_processor
def inject_oauth():
    """Inject Catalog application oauth information for use by all templates.

    Creates and adds an anti-forgery state token to the session for oauth login
    authentication.

    This is because the login button will be displayed on all public pages.

    Returns:
      A dictionary that will contain information for user authentication.
    """
    if 'state' in session:
        state = session['state']
    else:
        state = ''.join(
            random.choice(
                string.ascii_uppercase + string.digits
            ) for x in xrange(32)
        )
        session['state'] = state

    username = ''
    picture = ''
    is_logged_in = 'user_id' in session
    if is_logged_in:
        username = session['username']
        picture = session['picture']
    information = dict(
        client_id=CLIENT_ID,
        state=state,
        user_name=username,
        picture=picture,
        is_logged_in=is_logged_in
    )
    return information


@app.route('/')
@app.route('/catalog')
def dashboard():
    """Catalog main page.

    Returns:
        A HTML page representing the index page.
    """
    catagories = Catagory.query.all()
    catagory_items = CatagoryItem.\
        query.\
        order_by(CatagoryItem.id.desc()).\
        limit(9)
    for catagory_item in catagory_items:
        if catagory_item.user_id is not None and catagory_item.picture:
            catagory_item.picture = url_for(
                'static',
                filename='uploads/{0}'.format(catagory_item.picture)
            )
    return render_template(
        'index.html',
        catagory_items=catagory_items,
        catagories=catagories
    )


@app.route('/catagory/<int:catagory_id>/item')
def view_catagory(catagory_id):
    """Catagory page.

    Lists items belonging to the catagory for users to view. Allow a user who
    is logged in to create an item.

    Returns:
      A HTML page representing a catagory.
    """
    catagories = Catagory.query.all()
    catagory = Catagory.query.filter_by(id=catagory_id).one()
    catagory_items = CatagoryItem.\
        query.\
        filter_by(catagory_id=catagory_id).\
        all()

    return render_template(
        'catagory.html',
        catagories=catagories,
        name=catagory.name,
        items=catagory_items
    )


@app.route('/book/<int:catagory_item_id>')
def view_catagory_item(catagory_item_id):
    """Catagory iem page.

    Display catagory item information. If user is authorized, allow user to
    edit or delete item.

    Returns:
      A HTML page representing a catagory item.
    """
    is_authorized = False
    catagory_item = CatagoryItem.\
        query.\
        filter_by(id=catagory_item_id).\
        one()

    # If there is no user_id associated with catagory_id, then it was created
    # by the system as test data. Test data hot links to images found on the
    # internet; otherwise, if there is an image uploaded by a user it will be
    # in the uploads folder.

    if catagory_item.user_id is not None and catagory_item.picture:
        catagory_item.picture = url_for(
            'static',
            filename='uploads/{0}'.format(catagory_item.picture)
        )

    if 'user_id' in session:
        is_authorized = catagory_item.user_id == session['user_id']