import os
import traceback
from pathlib import Path
from datetime import datetime
from flask import current_app, jsonify, request
from flask_restful import Resource
from flask_restful.reqparse import RequestParser
from flask_jwt_extended import ( jwt_required, get_jwt_identity )
from werkzeug.datastructures import FileStorage
from werkzeug.utils import secure_filename
from application.config import config
from application.signal_manager import signalManager
from models.app import  postAppSchema, deleteAppSchema, getListAppSchema, getListAppsSchema, getAppSchema, putAppSchema
from webcreator.log import logger
from webcreator.response import ResponseCode, response_result

class AppResourceList(Resource):
    def __init__(self):
        # 特殊参数,即不是从json获取参数的接口,可以将这个注释打开
        self.parser = RequestParser()

    @jwt_required(locations=["headers"])
    def get(self):
        # 特殊参数,即不是从json获取参数的接口,可以将这个注释打开
        self.parser.add_argument('User-Agent', location='headers')
        self.parser.add_argument("app", type=str, location="args", nullable=True, required=False)
        self.parser.add_argument("scope", type=str, location="args", nullable=True, required=False)
        self.parser.add_argument("app_name", type=str, location="args", nullable=True, required=False)
        self.parser.add_argument("app_version", type=str, location="args", nullable=True, required=False)
        self.parser.add_argument("category", type=str, location="args", nullable=True, required=False)
        self.parser.add_argument("app_screen_size", type=str, location="args", nullable=True, required=False)
        self.parser.add_argument("app_arch", type=str, location="args", nullable=True, required=False)
        self.parser.add_argument("page", type=int, location="args", default=1)
        self.parser.add_argument("pageSize", type=int, location="args", default=15)
        args = self.parser.parse_args()

        try:
            jwt = get_jwt_identity()
            # data = getListAppSchema.load(args)
            data = dict()
            for key, value in args.items():
                if value != None:
                    data[key] = value
            result, message = signalManager.actionGetListApp.emit(data, jwt)
            json_dumps = getListAppSchema.dump(result)
            if result:
                if isinstance(result, list):
                    json_dumps = result
                    return response_result(ResponseCode.HTTP_SUCCESS, data=json_dumps)
                else:
                    json_dumps = getListAppsSchema.dump(result.items)
                    for item in json_dumps:
                        item['file_dir'] = os.path.dirname(item['download_url'])
                    return response_result(ResponseCode.HTTP_SUCCESS, data=json_dumps, total=result.total, pageSize=args.pageSize)
            return response_result(message)
        except Exception as e:
            traceback.print_exc()
            current_app.logger.error(e)
            return response_result(ResponseCode.HTTP_SERVER_ERROR)

    @jwt_required(locations=["headers"])
    def post(self):
        self.parser.add_argument('User-Agent', location='headers')
        self.parser.add_argument("meta_data", type=str, location="form", default="{}", required=False)
        self.parser.add_argument("app_name", type=str, location="form", required=True)
        self.parser.add_argument("app_version", type=str, location="form", required=True)
        self.parser.add_argument("category", type=str, location="form", required=True)
        self.parser.add_argument("app_screen_size", type=str, location="form", required=True)
        self.parser.add_argument("app_arch", type=str, location="form", required=True)
        self.parser.add_argument("algorithm", type=str, location="form", required=True)
        self.parser.add_argument("remarks", type=str, location="form", required=True)
        self.parser.add_argument("logo", type=FileStorage, location="files", required=True)
        self.parser.add_argument("fileList", type=FileStorage, location="files", required=True)
        args = self.parser.parse_args()

        try:
            jwt = get_jwt_identity()

            # 获取request.files参数
            # json_payload = request.json
            params = postAppSchema.load(args)

            now_str = datetime.now().strftime("%Y%m%d%H%M%S")
            # 获取相对路径
            dirname = "{}-{}-{}-{}".format(params["app_name"], params["app_version"], params["category"], now_str)
            relative_path = Path(config.UPLOAD_ROOT_DIR)
            # 获取最终存储的绝对路径
            upload_path = Path(config.EPK_DIR).joinpath(dirname)

            if not upload_path.exists():
                os.makedirs(upload_path.resolve().as_posix())

            files = []
            # 应用logo
            logo = request.files.get("logo") # args.get('picture')
            if logo:
                filename = secure_filename(logo.filename)
                file_path = upload_path.joinpath(filename)
                logo.save(file_path)
                params.update({ "app_icon": file_path.relative_to(relative_path).as_posix() })

            # 应用源文件
            fileList = request.files.getlist('fileList')
            if fileList:
                upload_path = upload_path.joinpath("src")
                if not upload_path.exists():
                    os.mkdir(upload_path.resolve().as_posix())

                for f in fileList:
                    filename = secure_filename(f.filename)
                    file_path = upload_path.joinpath(filename)
                    f.save(file_path.resolve().as_posix())
                    files.append(file_path.relative_to(relative_path).as_posix())

            params.update({ "fileList": files, "epk_path": upload_path, 'real_ip': request.headers.get('X-Forwarded-For', '127.0.0.1') })
            result, message = signalManager.actionPostApp.emit(params, jwt)
            if result:
                return response_result(ResponseCode.HTTP_SUCCESS, data=result)
            return response_result(message)
        except Exception as e:
            traceback.print_exc()
            current_app.logger.error(e)
            return response_result(ResponseCode.HTTP_SERVER_ERROR)


class AppResource(Resource):
    def __init__(self):
        pass
        # 特殊参数,即不是从json获取参数的接口,可以将这个注释打开
        # self.parser = RequestParser()

    @jwt_required(locations=["headers"])
    def get(self, uuid):
        # 特殊参数,即不是从json获取参数的接口,可以将这个注释打开
        # self.parser.add_argument("page", type=int, location="args", default=1)
        # self.parser.add_argument("pageSize", type=int, location="args", default=15)
        # args = self.parser.parse_args()

        try:
            jwt = get_jwt_identity()
            result, message = signalManager.actionGetApp.emit(uuid, jwt)
            if result:
                return response_result(ResponseCode.HTTP_SUCCESS, data=result)
            return response_result(message)
        except Exception as e:
            traceback.print_exc()
            current_app.logger.error(e)
            return response_result(ResponseCode.HTTP_SERVER_ERROR)


    @jwt_required(locations=["headers"])
    def put(self, uuid):
        try:
            jwt = get_jwt_identity()
            json_payload = request.json
            data = putAppSchema.load(json_payload)
            result, message = signalManager.actionPutApp.emit(uuid, data, jwt)
            if result:
                return response_result(ResponseCode.HTTP_SUCCESS, data=result)
            return response_result(message)
        except Exception as e:
            traceback.print_exc()
            current_app.logger.error(e)
            return response_result(ResponseCode.HTTP_SERVER_ERROR)


    @jwt_required(locations=["headers"])
    def delete(self, uuid):
        try:
            json_payload = request.json
            # data = deleteAppSchema.load(json_payload)
            print("========>", uuid, json_payload)
            result, message = signalManager.actionDeleteApp.emit(uuid)
            if result:
                return response_result(ResponseCode.HTTP_SUCCESS, data=result)
            return response_result(message)
        except Exception as e:
            traceback.print_exc()
            current_app.logger.error(e)
            return response_result(ResponseCode.HTTP_SERVER_ERROR)