from gevent import monkey
monkey.patch_all()

import json
import time

from flask import Flask, request
from log import Log
from config import set_config
from recommend import video_homepage_recommend, video_relevant_recommend
from category import get_category_videos
from video_recall import PoolRecall
from db_helper import RedisHelper
import traceback
import ast
from gevent.pywsgi import WSGIServer
from multiprocessing import cpu_count, Process
from utils import update_video_w_h_rate
#from werkzeug.middleware.profiler import ProfilerMiddleware
app = Flask(__name__)
#app.wsgi_app = ProfilerMiddleware(app.wsgi_app)
log_ = Log()
config_ = set_config()


@app.route('/healthcheck')
def health_check():
    return 'ok!'


# 首页推荐及tab分类
@app.route('/applet/video/homepage/recommend', methods=['GET', 'POST'])
def homepage_recommend():
    start_time = time.time()
    try:
        request_data = json.loads(request.get_data())
        mid = request_data.get('mid')
        uid = request_data.get('uid')
        category_id = request_data.get('categoryId')
        size = request_data.get('size')
        app_type = request_data.get('appType')
        algo_type = request_data.get('algoType')
        client_info = request_data.get('clientInfo')
        log_.info('homepage_recommend request data: {}'.format(request_data))
        # size默认为10
        if not size:
            size = 10
        if category_id in config_.CATEGORY['recommend']:
            # 推荐
            videos = video_homepage_recommend(mid=mid, uid=uid, size=size, app_type=app_type,
                                              algo_type=algo_type, client_info=client_info)
            result = {'code': 200, 'message': 'success', 'data': {'videos': videos}}
            log_.info('category_id: {}, mid: {}, uid: {}, result: {}, execute time = {}ms'.format(
                category_id, mid, uid, result, (time.time() - start_time)*1000))
            return json.dumps(result)
        elif category_id in config_.CATEGORY['other']:
            # 其他类别
            videos = get_category_videos()
            result = {'code': 200, 'message': 'success', 'data': {'videos': videos}}
            log_.info('category_id: {}, mid: {}, uid: {}, result: {}, execute time = {}ms'.format(
                category_id, mid, uid, result, (time.time() - start_time) * 1000))
            return json.dumps(result)
        else:
            log_.error('categoryId error, categoryId = {}'.format(category_id))
            result = {'code': -1, 'message': 'categoryId error'}
            return json.dumps(result)

    except Exception as e:
        log_.error(traceback.format_exc())
        result = {'code': -1, 'message': 'fail'}
        return json.dumps(result)


# 相关推荐
@app.route('/applet/video/relevant/recommend', methods=['GET', 'POST'])
def relevant_recommend():
    start_time = time.time()
    try:
        request_data = json.loads(request.get_data())
        mid = request_data.get('mid')
        uid = request_data.get('uid')
        video_id = request_data.get('videoId')
        up_uid = request_data.get('upUid')
        share_mid = request_data.get('shareMid')
        share_uid = request_data.get('shareUid')
        page_num = request_data.get('pageNum', 1)
        page_size = request_data.get('pageSize', 10)
        app_type = request_data.get('appType')
        log_.info('relevant_recommend request data: {}'.format(request_data))

        videos = video_relevant_recommend(video_id=video_id, mid=mid, uid=uid, size=page_size, app_type=app_type)

        result = {'code': 200, 'message': 'success', 'data': {'videos': videos}}
        log_.info('app_type: {}, mid: {}, uid: {}, relevant-result: {}, execute time = {}ms'.format(
            app_type, mid, uid, result, (time.time() - start_time) * 1000))
        return json.dumps(result)
    except Exception as e:
        log_.error(traceback.format_exc())
        result = {'code': -1, 'message': 'fail'}
        return json.dumps(result)


# 管理后台实时修改rov
@app.route('/applet/video/update/rov', methods=['GET', 'POST'])
def update_rov():
    # result = {'code': 200, 'message': 'success'}
    # log_.info('result: {}'.format(result))
    # return json.dumps(result)
    # ##### 暂时关闭该接口
    try:
        request_data = json.loads(request.get_data())
        log_.info('update_rov request data: {}'.format(request_data))
        # app_type = request_data.get('appType')
        video_id = request_data.get('videoId')
        rov_score = request_data.get('rovScore')
        redis_helper = RedisHelper()
        # 将修改ROV值视频的 videoId 和 rovScore 存入对应的redis中
        redis_helper.update_score_with_value(key_name=config_.UPDATE_ROV_KEY_NAME, value=video_id, score=rov_score)
        # 判断该视频是否为 横屏视频,如果是则 存入rov召回池横屏视频 redis 中
        update_video_w_h_rate(video_id=int(video_id), key_name=config_.W_H_RATE_UP_1_VIDEO_LIST_KEY_NAME['rov_recall'])
        result = {'code': 200, 'message': 'update rov success'}
        log_.info('result: {}'.format(result))
        return json.dumps(result)
    except Exception as e:
        log_.error(traceback.format_exc())
        result = {'code': -1, 'message': 'update rov fail'}
        return json.dumps(result)


# app热榜
@app.route('/app/video/hot_list', methods=['GET', 'POST'])
def app_video_hot_list():
    try:
        page_size= 10
        request_data = request.get_data()
        request_data = json.loads(request_data)
        page = request_data.get('page', 0)
        log_.info('app_video_hot_list request data: {}'.format(request_data))

        redis_helper = RedisHelper()
        datas = redis_helper.get_data_from_redis('app_video_hot_list')

        if datas is None or len(datas) == 0:
            result = {'code': -1, 'message': 'no data'}
            log_.info('result: {}'.format(result))
            return json.dumps(result)
        datas = ast.literal_eval(datas)
        total_page = int(len(datas)/page_size)
        if page > total_page -1 :
            result = {'code': -1, 'message': 'page exceed max'}
            log_.info('result: {}'.format(result))
            return json.dumps(result)

        result = {'code': 200, 'message': '', 'data':{'total_page':total_page, 'hot_list':datas[page*page_size:page*page_size+page_size]}}
        log_.info('result: {}'.format(result))
        return json.dumps(result)

    except Exception as e:
        log_.error(e)
        print(traceback.format_exc())
        result = {'code': -1, 'message': 'fail'}
        return json.dumps(result)


def serve_forever(ip='0.0.0.0', port=5001):
    pywsgi.WSGIServer((ip, port), app).serve_forever()


def apprun(MULTI_PROCESS=True, ip='0.0.0.0', port=5001):
    if MULTI_PROCESS == False:
        WSGIServer((ip, port), app).serve_forever()
    else:
        mulserver = WSGIServer((ip, port), app)
        mulserver.start()
 
        def server_forever():
            mulserver.start_accepting()
            mulserver._stop_event.wait()
 
        #for i in range(cpu_count()):
        for i in range(3):
            p = Process(target=server_forever)
            p.start()


if __name__ == '__main__':
    
    #app.run()
    #server = pywsgi.WSGIServer(('0.0.0.0', 5000), app)
    #server.serve_forever()
    apprun()