#!/usr/bin/env python
# -*- coding: utf-8 -*-

##############################################################################
#  Copyright Kitware Inc.
#
#  Licensed under the Apache License, Version 2.0 ( the "License" );
#  you may not use this file except in compliance with the License.
#  You may obtain a copy of the License at
#
#    http://www.apache.org/licenses/LICENSE-2.0
#
#  Unless required by applicable law or agreed to in writing, software
#  distributed under the License is distributed on an "AS IS" BASIS,
#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#  See the License for the specific language governing permissions and
#  limitations under the License.
##############################################################################

import io
import os
import json
from bson.objectid import ObjectId

from girder.api import access
from girder.api.describe import autoDescribeRoute, Description
from girder.constants import AccessType
from girder.api.rest import Resource, setResponseHeader, rawResponse
from girder.models.setting import Setting
from ..models.post import Post


class PostResource(Resource):

    def __init__(self):
        super(PostResource, self).__init__()

        self.resourceName = 'post'
        self.route('GET', (':postId',), self.getPost)
        self.route('GET', ('postids',), self.getPostIds)
        self.route('PUT', (':postId', 'result',), self.updateResult)
        self.route('PUT', (':postId', 'imageresult',), self.updateImageResult)
        self.route('GET', (':postId', 'image',), self.getImage)
        self.route('POST', ('import', ':path'), self.importData)
        self.route('PUT', ('setimagepath', ':path'), self.setImagePath)
        # not used for now
        self.route('GET', (':id', 'next'), self.getNext)
        self.route('GET', (':id', 'previous'), self.getPrevious)

    # @autoDescribeRoute(
    #     Description('')
    #     .modelParam('id', model=Post)
    #     .errorResponse()
    #     .errorResponse('Read access was denied on the item.', 403)
    # )
    # @access.user
    # def get(self, post, params):
    #     return post

    @autoDescribeRoute(
        Description('')
        .param('postId', 'The post id', paramType='path')
        .errorResponse()
    )
    @access.user
    def getPost(self, postId, params):
        return Post().getByPostId(postId)

    @autoDescribeRoute(
        Description('')
        .errorResponse()
    )
    @access.user
    def getPostIds(self, params):
        posts = list(Post().find({}, fields={'original.id': 1, '_id': 0}))
        return [post['original']['id'] for post in posts]

    @access.user
    @autoDescribeRoute(
        Description('')
        .param('postId', 'The post id', paramType='path')
        .jsonParam('result', '', paramType='body', requireObject=True)
        .errorResponse()
    )
    def updateResult(self, postId, result, params):
        user = self.getCurrentUser()
        post = Post().getByPostId(postId)
        if post:
            post['result'] = result['result']
            post['resultUser'] = user['login']
            Post().save(post)

    @access.user
    @autoDescribeRoute(
        Description('')
        .param('postId', 'The post id', paramType='path')
        .jsonParam('result', '', paramType='body', requireObject=True)
        .errorResponse()
    )
    def updateImageResult(self, postId, result, params):
        user = self.getCurrentUser()
        post = Post().getByPostId(postId)
        if post:
            post['imageResult'] = result['imageResult']
            post['resultUser'] = user['login']
            Post().save(post)

    @access.user
    @autoDescribeRoute(
        Description('')
        .param('path', 'The absolute path of the image directory', paramType='path')
        .errorResponse()
    )
    def setImagePath(self, path, params):
        Setting().set('instagram_labelling.image_path', path)

    @access.user
    @access.cookie
    @rawResponse
    @autoDescribeRoute(
        Description('')
        .param('postId', 'The post id', paramType='path')
        .produces('image/jpeg')
        .errorResponse()
    )
    def getImage(self, postId, params):
        setResponseHeader('Content-Type', 'image/jpeg')
        path = Setting().get('instagram_labelling.image_path')
        filePath = os.path.join(path, postId + '.jpg')
        # print os.path.exists(filePath)
        file = io.open(os.path.join(path, postId + '.jpg'), 'rb')
        return file

    @access.user
    @autoDescribeRoute(
        Description('')
        .param('path', 'Absolute path of the json data', paramType='path')
        .errorResponse()
    )
    def importData(self, path, params):
        with io.open(path, 'r') as f:
            data = json.load(f)
        Post().collection.delete_many({})
        for post in data:
            Post().save({
                'original': post,
                'result': None,
                'imageResult': None,
                'resultUser': None
            })
        return

    @autoDescribeRoute(
        Description('')
        .param('id', 'The record id', paramType='path')
        .errorResponse()
    )
    @access.user
    def getNext(self, id, params):
        posts = list(Post().find({'_id': {'$gt': ObjectId(id)}}).sort('_id').limit(1))
        if len(posts) == 0:
            return None
        return posts[0]

    @autoDescribeRoute(
        Description('')
        .param('id', 'The record id', paramType='path')
        .errorResponse()
    )
    @access.user
    def getPrevious(self, id, params):
        posts = list(Post().find({'_id': {'$lt': ObjectId(id)}}).sort('_id', -1).limit(1))
        if len(posts) == 0:
            return None
        return posts[0]
