'''
Author: your name
Date: 2021-07-09 12:39:40
LastEditTime: 2021-07-19 13:58:36
LastEditors: Please set LastEditors
Description: In User Settings Edit
FilePath: \evm-store\tools\build_out\views\file.py
'''

import traceback
from pathlib import Path
from flask import current_app, jsonify, request, make_response, Response
from flask_restful import Resource, fields
from marshmallow import Schema, fields
from werkzeug.datastructures import FileStorage
from flask_restful.reqparse import RequestParser
from flask_jwt_extended import ( jwt_required, get_jwt_identity )
from application.signal_manager import signalManager
from webcreator.log import logger
from webcreator.response import ResponseCode, response_result

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

    @jwt_required(locations=["headers"])
    def get(self):
        # 特殊参数，即不是从json获取参数的接口，可以将这个注释打开
        self.parser.add_argument("path", type=str, location="args", required=False)
        args = self.parser.parse_args()

        try:
            jwt = get_jwt_identity()
            result, message = signalManager.actionGetFileInit.emit(args.path, jwt)
            if result:
                return { 'config': result, 'result': { 'message': None, 'status': "success" } }
            return { 'information': list(message), 'result': { 'message': "no data", 'status': "fail" } }
        except Exception as e:
            current_app.logger.error(e)
            return response_result(ResponseCode.HTTP_SERVER_ERROR)


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

    @jwt_required(locations=["headers"])
    def get(self):
        # 特殊参数，即不是从json获取参数的接口，可以将这个注释打开
        self.parser.add_argument("disk", type=str, location="args", required=True)
        self.parser.add_argument("path", type=str, location="args", required=False, default=None)
        self.parser.add_argument("root", type=str, location="args", required=True)
        args = self.parser.parse_args()

        try:
            result, message = signalManager.actionGetFileContent.emit(args.disk, args.path, args.root)
            if result:
                response = { 'result': { 'message': None, 'status': "success" } }
                response.update(result)
                return response
            return { 'information': list(message), 'result': { 'message': "no data", 'status': "fail" } }
        except Exception as e:
            traceback.print_exc()
            current_app.logger.error(e)
            return response_result(ResponseCode.HTTP_SERVER_ERROR)

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

    @jwt_required(locations=["headers"])
    def get(self):
        # 特殊参数，即不是从json获取参数的接口，可以将这个注释打开
        self.parser.add_argument("disk", type=str, location="args", required=True)
        self.parser.add_argument("path", type=str, location="args", required=False)
        self.parser.add_argument("root", type=str, location="args", required=True)
        args = self.parser.parse_args()

        try:
            result, message = signalManager.actionGetFileTree.emit(args.disk, args.path, args.root)
            if result:
                response = { 'result': { 'message': None, 'status': "success" }, 'directories': None }
                response.update({ 'directories': result })
                return response
            return { 'information': list(message), 'result': { 'message': "no data", 'status': "fail" } }
        except Exception as e:
            traceback.print_exc()
            current_app.logger.error(e)
            return response_result(ResponseCode.HTTP_SERVER_ERROR)

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

    def get(self):
        # 特殊参数，即不是从json获取参数的接口，可以将这个注释打开
        self.parser.add_argument("disk", type=str, location="args", required=True)
        self.parser.add_argument("path", type=str, location="args", required=False)
        args = self.parser.parse_args()

        try:
            result, message = signalManager.actionGetFileDisk.emit(args.disk)
            if result:
                return { 'information': list(message), 'result': { 'message': "Disk selected!", 'status': "success" } }
            return { 'information': list(message), 'result': { 'message': "no data", 'status': "fail" } }
        except Exception as e:
            current_app.logger.error(e)
            return response_result(ResponseCode.HTTP_SERVER_ERROR)

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

    def post(self):
        # logger.info(request.form)
        self.parser.add_argument("disk", type=str, location="form", required=True)
        self.parser.add_argument("path", type=str, location="form", nullable=False, required=True)
        self.parser.add_argument("file", type=FileStorage, location="files", required=True)
        args = self.parser.parse_args()

        try:
            # logger.info(args.path)
            file = request.files.get("file") # args.get('file')
            result, message = signalManager.actionPostFileUpdate.emit(args.disk, args.path, file)
            if result:
                return { 'config': result, 'result': { 'message': "file update success", 'status': "success" } }
            return { 'information': list(message), 'result': { 'message': "no data", 'status': "fail" } }
        except Exception as e:
            current_app.logger.error(e)
            return response_result(ResponseCode.HTTP_SERVER_ERROR)

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

    def post(self):
        self.parser.add_argument("disk", type=str, location="form", required=True)
        self.parser.add_argument("path", type=str, location="form", required=True)
        self.parser.add_argument("overwrite", type=int, location="form", default=0, required=True)
        self.parser.add_argument("files", type=FileStorage, location="files", required=True, action='append')
        args = self.parser.parse_args()

        try:
            fileList = request.files.getlist('files')
            result, message = signalManager.actionPostFileUpload.emit(args.disk, args.path, args.overwrite, fileList)
            if result:
                return { 'config': result, 'result': { 'message': None, 'status': "success" } }
            return { 'information': list(message), 'result': { 'message': "no data", 'status': "fail" } }
        except Exception as e:
            current_app.logger.error(e)
            return response_result(ResponseCode.HTTP_SERVER_ERROR)

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

    def post(self):
        # 特殊参数，即不是从json获取参数的接口，可以将这个注释打开
        self.parser.add_argument("disk", type=str, location="json", required=True)
        # self.parser.add_argument("items", type=fields.Raw, location="json", required=True) # items: [{path: "code/app.php", type: "file"}]
        args = self.parser.parse_args()

        try:
            json_payload = request.json
            logger.info(json_payload)
            if not json_payload:
                return False, ResponseCode.HTTP_INVAILD_REQUEST
            result, message = signalManager.actionPostFileDelete.emit(**json_payload)
            if result:
                return { 'config': result, 'result': { 'message': None, 'status': "success" } }
            return { 'information': list(message), 'result': { 'message': "no data", 'status': "fail" } }
        except Exception as e:
            traceback.print_exc()
            current_app.logger.error(e)
            return response_result(ResponseCode.HTTP_SERVER_ERROR)

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

    def post(self):
        # 特殊参数，即不是从json获取参数的接口，可以将这个注释打开
        self.parser.add_argument("disk", type=str, location="json", required=True)
        self.parser.add_argument("path", type=str, location="json", required=True)
        self.parser.add_argument("name", type=str, location="json", required=True)
        args = self.parser.parse_args()

        try:
            result, message = signalManager.actionPostFileCreate.emit(args.disk, args.path, args.name)
            if result:
                return { 'config': result, 'result': { 'message': None, 'status': "success" } }
            return { 'information': list(message), 'result': { 'message': "no data", 'status': "fail" } }
        except Exception as e:
            current_app.logger.error(e)
            return response_result(ResponseCode.HTTP_SERVER_ERROR)

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

    def post(self):
        # 特殊参数，即不是从json获取参数的接口，可以将这个注释打开
        self.parser.add_argument("disk", type=str, location="json", required=True)
        self.parser.add_argument("path", type=str, location="json", required=True)
        self.parser.add_argument("name", type=str, location="json", required=True)
        args = self.parser.parse_args()

        try:
            result, message = signalManager.actionPostFileCreateDir.emit(args.disk, args.path, args.name)
            if result:
                return { 'config': result, 'result': { 'message': None, 'status': "success" } }
            return { 'information': list(message), 'result': { 'message': "no data", 'status': "fail" } }
        except Exception as e:
            current_app.logger.error(e)
            return response_result(ResponseCode.HTTP_SERVER_ERROR)

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

    def post(self):
        # 特殊参数，即不是从json获取参数的接口，可以将这个注释打开
        self.parser.add_argument("disk", type=str, location="json", required=True)
        self.parser.add_argument("clipboard", type=dict, location="json", required=True)
        args = self.parser.parse_args()

        try:
            result, message = signalManager.actionPostFilePaste.emit(args.disk, args.items)
            if result:
                return { 'config': result, 'result': { 'message': None, 'status': "success" } }
            return { 'information': list(message), 'result': { 'message': "no data", 'status': "fail" } }
        except Exception as e:
            current_app.logger.error(e)
            return response_result(ResponseCode.HTTP_SERVER_ERROR)

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

    def get(self):
        # 特殊参数，即不是从json获取参数的接口，可以将这个注释打开
        self.parser.add_argument("disk", type=str, location="args", required=True)
        self.parser.add_argument("path", type=str, location="args", required=True)
        args = self.parser.parse_args()

        try:
            result, message = signalManager.actionGetFileDown.emit(args.disk, args.path)
            if result:
                resp, mime = result
                # return Response(resp, mimetype='text/xml')
                return Response(resp, content_type='{}; charset=utf-8'.format(mime))
            return { 'information': list(message), 'result': { 'message': "no data", 'status': "fail" } }
        except Exception as e:
            traceback.print_exc()
            current_app.logger.error(e)
            return response_result(ResponseCode.HTTP_SERVER_ERROR)


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

    @jwt_required(locations=["headers"])
    def get(self):
        # 特殊参数，即不是从json获取参数的接口，可以将这个注释打开
        self.parser.add_argument("disk", type=str, location="args", required=True)
        self.parser.add_argument("path", type=str, location="args", required=True)
        args = self.parser.parse_args()

        try:
            result, message = signalManager.actionGetFilePreview.emit(args.disk, args.path)
            if result:
                content, mime = result
                resp = make_response(content)
                resp.mimetype = mime
                return resp
            return { 'information': list(message), 'result': { 'message': "no data", 'status': "fail" } }
        except Exception as e:
            traceback.print_exc()
            current_app.logger.error(e)
            return response_result(ResponseCode.HTTP_SERVER_ERROR)
