# -*- coding: utf-8 -*-
# Copyright 2020 Green Valley Belgium NV
#
# 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.
#
# @@license_version:1.7@@

import json
from Queue import Queue, Empty
from threading import Thread
from types import NoneType

from google.appengine.ext import db

from mcfw.rpc import returns, arguments
from rogerthat.bizz import app as bizz_app
from rogerthat.bizz.communities.communities import get_community
from rogerthat.bizz.service import validate_app_admin, get_and_validate_app_id_for_service_identity_user
from rogerthat.dal.app import get_app_translations
from rogerthat.dal.friend import get_friends_map_key_by_user
from rogerthat.dal.profile import get_user_profiles_by_app_id, get_service_profile
from rogerthat.dal.registration import list_installations_by_app, get_installation_logs_by_installation, \
    get_mobiles_and_profiles_for_installations
from rogerthat.dal.service import get_default_service_identity
from rogerthat.models import Installation, ServiceProfile
from rogerthat.rpc import users
from rogerthat.rpc.models import ServiceAPICallback
from rogerthat.rpc.rpc import mapping
from rogerthat.rpc.service import service_api, service_api_callback
from rogerthat.to.app import AppInfoTO, AppUserListResultTO, AppUserTO, AppSettingsTO, PutLoyaltyUserResultTO, \
    AppTranslationTO
from rogerthat.to.installation import InstallationListTO, InstallationLogTO, InstallationTO
from rogerthat.utils.app import create_app_user, get_app_user_tuple
from rogerthat.utils.crypto import decrypt, encrypt
from rogerthat.utils.service import add_slash_default


#############################################
# DO NOT DOCUMENT THIS SERVICE API FUNCTION #
@service_api(function=u'app.get_info')
@returns(AppInfoTO)
@arguments(app_id=unicode)
def get_info(app_id):
    app = bizz_app.get_app(app_id)
    return AppInfoTO.fromModel(app) if app else None


@service_api(function=u'app.put_user_regexes')
@returns()
@arguments(app_id=unicode, regexes=[unicode])
def put_user_regexes(app_id, regexes):
    service_user = users.get_current_user()
    validate_app_admin(service_user, [app_id])
    bizz_app.put_user_regexes(service_user, app_id, regexes)


@service_api(function=u'app.del_user_regexes')
@returns()
@arguments(app_id=unicode, regexes=[unicode])
def del_user_regexes(app_id, regexes):
    service_user = users.get_current_user()
    validate_app_admin(service_user, [app_id])
    bizz_app.del_user_regexes(service_user, app_id, regexes)


@service_api(function=u'app.put_profile_data')
@returns(NoneType)
@arguments(email=unicode, profile_data=unicode, app_id=unicode)
def put_profile_data(email, profile_data, app_id):
    from rogerthat.bizz.profile import set_profile_data
    service_user = users.get_current_user()
    validate_app_admin(service_user, [app_id])
    set_profile_data(service_user, create_app_user(users.User(email), app_id), profile_data)


@service_api(function=u'app.del_profile_data')
@returns(NoneType)
@arguments(email=unicode, profile_data_keys=[unicode], app_id=unicode)
def del_profile_data(email, profile_data_keys, app_id):
    from rogerthat.bizz.profile import set_profile_data
    service_user = users.get_current_user()
    validate_app_admin(service_user, [app_id])
    set_profile_data(service_user,
                     create_app_user(users.User(email), app_id),
                     json.dumps(dict(((key, None) for key in profile_data_keys))))


@service_api(function=u'app.list_users')
@returns(AppUserListResultTO)
@arguments(app_id=unicode, cursor=unicode)
def list_users(app_id, cursor):
    service_user = users.get_current_user()
    validate_app_admin(service_user, [app_id])

    if cursor:
        cursor = decrypt(service_user, cursor)

    query = get_user_profiles_by_app_id(app_id)
    query.with_cursor(cursor)
    user_profiles = query.fetch(1000)
    cursor = query.cursor()
    extra_key = query.fetch(1)

    result = AppUserListResultTO()
    result.cursor = unicode(encrypt(service_user, cursor)) if len(extra_key) > 0 else None

    work = Queue()
    results = Queue()
    for items in [user_profiles[x:x + 50] for x in xrange(0, len(user_profiles), 50)]:
        work.put(items)

    def slave():
        while True:
            try:
                user_profiles = work.get_nowait()
            except Empty:
                break  # No more work, goodbye
            try:
                friendMaps = db.get([get_friends_map_key_by_user(user_profile.user) for user_profile in user_profiles])