#!/usr/bin/env python
# -*- coding: utf_8 -*-
import os
import json
import logging
import traceback
from datetime import datetime

from flask import Blueprint, request
from werkzeug.utils import secure_filename

from app import config, signalManager
from fullstack.login import Auth
from fullstack.validation import validate_schema
from fullstack.response import ResponseCode, response_result
from schema.apps import AddSchema, DeleteSchema, QuerySchema, UpdateSchema
from schema.build_logs import AddSchema as LogAddScheme, QuerySchema as LogQuerySchema

logger = logging.getLogger(__name__)

apps_api = Blueprint("apps_api", __name__, url_prefix="/api/v1/%s/apps" % config['NAME'])

@apps_api.route("/add", methods=['POST'])
@validate_schema(AddSchema)
@Auth.auth_required
def add():
    try:
        params = request.schema_data

        dtNowString = datetime.now().strftime("%Y%m%d%H%M%S")
        # 获取相对路径
        dirname = "{}-{}-{}-{}".format(params["app_name"], params["app_version"], params["category"], dtNowString)
        relative_path = os.sep.join([config.get("EPK_DIR"), dirname])
        # 获取最终存储的绝对路径
        upload_path = os.path.normpath(os.sep.join([config.get("UPLOAD_PATH"), relative_path]))

        if not os.path.exists(upload_path):
            os.makedirs(upload_path)

        files = []
        logo = request.files.get("logo")
        if logo:
            filename = secure_filename(logo.filename)
            file_path = os.sep.join([upload_path, filename])
            file_path = os.path.normpath(file_path)
            logo.save(file_path)
            params.update({ "app_icon": file_path })

        fileList = request.files.getlist('fileList')
        if fileList:
            upload_path = os.sep.join([upload_path, "src"])
            if not os.path.exists(upload_path):
                os.mkdir(upload_path)

            for f in fileList:
                filename = secure_filename(f.filename)
                file_path = os.sep.join([upload_path, filename])
                file_path = os.path.normpath(file_path)
                f.save(file_path)
                files.append(file_path)

        # obj = dict()
        # obj['filename'] = binfile.filename
        # obj['content'] = binfile.stream.read()

        params.update({ "fileList": files, "epk_path": upload_path })

        user = request.current_user.get("id")
        isSuccess, message = signalManager.actionAddApp.emit(user, params)
        if isSuccess:
            return response_result(ResponseCode.OK, msg=message)
        else:
            return response_result(ResponseCode.REQUEST_ERROR, msg=message)
    except Exception as e:
        traceback.print_exc()
        logger.error(str(e))
        return response_result(ResponseCode.SERVER_ERROR, msg=str(e))

@apps_api.route("/delete/<uuid:id>", methods=['POST'])
@Auth.auth_required
def delete(id):
    try:
        user = request.current_user.get("id")
        isSuccess, message = signalManager.actionDeleteApp.emit(user, id)
        if isSuccess:
            return response_result(ResponseCode.OK, msg=message)
        else:
            return response_result(ResponseCode.REQUEST_ERROR, msg=message)
    except Exception as e:
        traceback.print_exc()
        logger.error(str(e))
        return response_result(ResponseCode.SERVER_ERROR)

@apps_api.route("/get", methods=["POST"])
@validate_schema(QuerySchema)
@Auth.auth_required
def get():
    try:
        user = request.current_user.get("id")
        result, message = signalManager.actionGetApp.emit(user, request.schema_data)
        if result:
            return response_result(ResponseCode.OK, data=result, msg=message)
        else:
            return response_result(ResponseCode.REQUEST_ERROR, msg=message)
    except Exception as e:
        traceback.print_exc()
        logger.error(str(e))
        return response_result(ResponseCode.SERVER_ERROR, msg=str(e))

@apps_api.route("/list", methods=['POST'])
@validate_schema(QuerySchema)
@Auth.auth_required
def get_list():
    try:
        user = request.current_user.get("id")
        result, count, message = signalManager.actionGetAppList.emit(user, request.schema_data)
        if result:
            return response_result(ResponseCode.OK, data=result, msg=message, count=count)
        else:
            return response_result(ResponseCode.REQUEST_ERROR, msg=message)
    except Exception as e:
        traceback.print_exc()
        logger.error(str(e))
        return response_result(ResponseCode.SERVER_ERROR)

@apps_api.route("/update/<uuid:id>", methods=['POST'])
@validate_schema(UpdateSchema)
@Auth.auth_required
def update(id):
    try:
        user = request.current_user.get("id")
        isSuccess, message = signalManager.actionUpdateApp.emit(user, id, request.schema_data)
        if isSuccess:
            return response_result(ResponseCode.OK, msg=message)
        else:
            return response_result(ResponseCode.REQUEST_ERROR, msg=message)
    except Exception as e:
        traceback.print_exc()
        logger.error(str(e))
        return response_result(ResponseCode.SERVER_ERROR)

@apps_api.route("/build/<uuid:id>", methods=['POST'])
@validate_schema(LogAddScheme)
@Auth.auth_required
def build_app(id):
    user = request.current_user.get("id")
    result, message = signalManager.actionAddBuildLog.emit(user, id)
    if result:
        return response_result(ResponseCode.OK, data=result, msg=message)
    else:
        return response_result(ResponseCode.NOTHING_CHANGE, msg=message)

@apps_api.route("/getBuildApp/<uuid:id>", methods=['POST'])
@Auth.auth_required
def get_build_app(id):
    user = request.current_user.get("id")
    result, message = signalManager.actionGetBuildLog.emit(user, id)
    if result:
        return response_result(ResponseCode.OK, data=result, msg=message)
    else:
        return response_result(ResponseCode.NOTHING_CHANGE, msg=message)

@apps_api.route("/buildLogs", methods=['POST'])
@validate_schema(LogQuerySchema)
@Auth.auth_required
def get_build_logs():
    user = request.current_user.get("id")
    result, count, message = signalManager.actionGetBuildLogList.emit(user, request.schema_data)
    if result:
        return response_result(ResponseCode.OK, data=result, msg=message, count=count)
    else:
        return response_result(ResponseCode.NOTHING_CHANGE, msg=message)