#!/usr/bin/env python
# encoding: utf-8

#
# The MIT License (MIT)
#
# Copyright (c) 2014 Hervé BREDIN (http://herve.niderb.fr/)
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
#

import logging
import requests
import json
from six.moves.urllib_parse import urljoin
import objectifier


class CamomileClient(object):

    def __init__(self, username, password, url, dict_or_objectifier):
        super(CamomileClient, self).__init__()

        # add trailing slash if missing
        self.url = url + ('/' if url[-1] != '/' else '')
        self.session = requests.Session()
        self.dict_or_objectifier = dict_or_objectifier
        self.login(username, password)

    ### common function ###
    def get(self, route):
        url = urljoin(self.url, route)
        r = self.session.get(url)
        if self.dict_or_objectifier:
            r = objectifier.Objectifier(r.json())          
        return r.status_code, r.json()

    def delete(self, route):
        url = urljoin(self.url, route)
        r = self.session.delete(url)
        if self.dict_or_objectifier:
            r = objectifier.Objectifier(r.json())          
        return r.status_code, r.json()

    def post(self, route, data):
        url = urljoin(self.url, route)
        r = self.session.post(url, data=json.dumps(data), headers={'Content-Type': 'application/json'})
        if self.dict_or_objectifier:
            r = objectifier.Objectifier(r.json())          
        return r.status_code, r.json()

    def put(self, route, data):
        url = urljoin(self.url, route)
        r = self.session.put(url, data=json.dumps(data), headers={'Content-Type': 'application/json'})
        if self.dict_or_objectifier:
            r = objectifier.Objectifier(r.json())          
        return r.status_code, r.json()

    ### authenticate ###
    def login(self, username, password):
        return self.post('login', {'username': username, 'password': password} )

    def logout(self):
        return self.post('logout', {})

    def me(self):
        return self.get('me')        

    ### user ###
    def create_user(self, data):
        return self.post('user', data)

    def get_all_user(self):
        return self.get('user')

    def get_user(self, id_user):
        return self.get('user/'+id_user)

    def update_user(self, id_user, data):
        return self.put('user/'+id_user, data)

    def delete_user(self, id_user):
        return self.delete('user/'+id_user)

    def get_all_group_of_a_user(self, id_user):
        return self.get('user/'+id_user+'/group')    

    ### group ###
    def create_group(self, data):
        return self.post('group', data)

    def get_all_group(self):
        return self.get('group')

    def get_group(self, id_group):
        return self.get('group/'+id_group)

    def update_group(self, id_group, data):
        return self.put('group/'+id_group, data)

    def delete_group(self, id_group):
        return self.delete('group/'+id_group)

    def add_user_to_a_group(self, id_group, id_user):
        return self.put('group/'+id_group+'/user/'+id_user, {})

    def remove_user_to_a_group(self, id_group, id_user):
        return self.delete('group/'+id_group+'/user/'+id_user)

    ### corpus ###
    def create_corpus(self, data):
        return self.post('corpus', data)

    def get_all_corpus(self):
        return self.get('corpus')

    def get_corpus(self, id_corpus):
        return self.get('corpus/'+id_corpus)

    def update_corpus(self, id_corpus, data):
        return self.put('corpus/'+id_corpus, data)

    def delete_corpus(self, id_corpus):
        return self.delete('corpus/'+id_corpus)

    def add_media(self, id_corpus, data):
        return self.post('corpus/'+id_corpus+'/media', data)

    def add_layer(self, id_corpus, data):
        return self.post('corpus/'+id_corpus+'/layer', data)

    def get_all_media_of_a_corpus(self, id_corpus):
        return self.get('corpus/'+id_corpus+'/media')

    def get_all_layer_of_a_corpus(self, id_corpus):
        return self.get('corpus/'+id_corpus+'/layer')

    def get_ACL_of_a_corpus(self, id_corpus):
        return self.get('corpus/'+id_corpus+'/ACL')

    def update_user_ACL_of_a_corpus(self, id_corpus, id_user, data):
        return self.put('corpus/'+id_corpus+'/user/'+id_user, data)

    def update_group_ACL_of_a_corpus(self, id_corpus, id_group, data):
        return self.put('corpus/'+id_corpus+'/group/'+id_group, data)

    def remove_user_from_ACL_of_a_corpus(self, id_corpus, id_user):
        return self.delete('corpus/'+id_corpus+'/user/'+id_user)

    def remove_group_from_ACL_of_a_corpus(self, id_corpus, id_group):
        return self.delete('corpus/'+id_corpus+'/group/'+id_group)

    ### media ###
    def get_all_media(self):
        return self.get('media')

    def get_media(self, id_media):
        return self.get('media/'+id_media)

    def update_media(self, id_media, data):
        return self.put('media/'+id_media, data)

    def delete_media(self, id_media):
        return self.delete('media/'+id_media)

    def get_media_video_stream(self, id_media):
        return self.get('media/'+id_media+'/video')

    def get_media_webm_stream(self, id_media):
        return self.get('media/'+id_media+'/webm')

    def get_media_mp4_stream(self, id_media):
        return self.get('media/'+id_media+'/mp4')

    def get_media_ogv_stream(self, id_media):
        return self.get('media/'+id_media+'/ogv')                

    ### layer ###
    def get_all_layer(self):
        return self.get('layer')

    def get_layer(self, id_layer):
        return self.get('layer/'+id_layer)

    def update_layer(self, id_layer, data):
        return self.put('layer/'+id_layer, data)

    def delete_layer(self, id_layer):
        return self.delete('layer/'+id_layer)

    def add_annotation(self, id_layer, data):
        return self.post('layer/'+id_layer+'/annotation', data)

    def get_all_annotation_of_a_layer(self, id_layer):
        return self.get('layer/'+id_layer+'/annotation')

    def get_ACL_of_a_layer(self, id_layer):
        return self.get('layer/'+id_layer+'/ACL')

    def update_user_ACL_of_a_layer(self, id_layer, id_user, data):
        return self.put('layer/'+id_layer+'/user/'+id_user, data)

    def update_group_ACL_of_a_layer(self, id_layer, id_group, data):
        return self.put('layer/'+id_layer+'/group/'+id_group, data)

    def remove_user_from_ACL_of_a_layer(self, id_layer, id_user):
        return self.delete('layer/'+id_layer+'/user/'+id_user)

    def remove_group_from_ACL_of_a_layer(self, id_layer, id_group):
        return self.delete('layer/'+id_layer+'/group/'+id_group)

    ### annotation ###
    def get_all_annotation(self):
        return self.get('annotation')

    def get_annotation(self, id_annotation):
        return self.get('annotation/'+id_annotation)

    def update_annotation(self, id_annotation, data):
        return self.put('annotation/'+id_annotation, data)

    def delete_annotation(self, id_annotation):
        return self.delete('annotation/'+id_annotation)

    ### queue ###
    def create_queue(self, data):
        return self.post('queue', data)

    def get_all_queue(self):
        return self.get('queue')

    def get_queue(self, id_queue):
        return self.get('queue/'+id_queue)

    def update_queue(self, id_queue, data):
        return self.put('queue/'+id_queue, data)

    def push_into_a_queue(self, id_queue, data):
        return self.put('queue/'+id_queue+'/next', data)

    def pop_a_queue(self, id_queue):
        return self.get('queue/'+id_queue+'/next')

    def delete_queue(self, id_queue):
        return self.delete('queue/'+id_queue)

    def get_date(self):
        return self.get('date')