'''
Author: your name
Date: 2021-07-19 14:29:33
LastEditTime: 2021-07-19 19:27:21
LastEditors: Please set LastEditors
Description: In User Settings Edit
FilePath: \evm-store\tools\build_out\views\api.py
'''
#!/usr/bin/env python
# -*- coding: utf_8 -*-

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.utils import secure_filename
from werkzeug.datastructures import FileStorage
from marshmallow.exceptions import ValidationError
from application.config import config
from application.signal_manager import signalManager
from webcreator.log import logger
from webcreator.utils.ccode import convert_string
from webcreator.response import ResponseCode, response_result

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

    @jwt_required(locations=["headers"])
    def post(self):
        self.parser.add_argument("review", type=int, location="json", default=0, required=True)
        self.parser.add_argument("app", type=str, location="json", required=False)
        args = self.parser.parse_args()

        try:
            jwt = get_jwt_identity()
            result, message = signalManager.actionPostAppReview.emit(args.app, args.review, jwt)
            if result:
                return response_result(message, data=result)
            return response_result(message)
        except ValidationError as e:
            return response_result(ResponseCode.HTTP_INVAILD_REQUEST, data=e.messages)
        except Exception as e:
            data = None
            if hasattr(e, 'args'):
                data = e.args
            traceback.print_exc()
            current_app.logger.error(e)
            return response_result(ResponseCode.HTTP_SERVER_ERROR, data=data)


class BuildAppResource(Resource):
    def __init__(self):
        self.parser = RequestParser()

    def post(self):
        self.parser.add_argument("access_key", type=str, location="form", required=True)
        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_desc", type=str, location="form", required=False)
        self.parser.add_argument("binfiles", type=FileStorage, location="files", required=True)
        args = self.parser.parse_args()

        try:
            data = dict()
            for key, value in args.items():
                if value != None:
                    data[key] = value

            if 'binfiles' in request.files:
                files = []
                dt = datetime.now().strftime("%Y%m%d%H%M%S")
                upload_path = Path(config.EPK_DIR).joinpath(args.access_key).joinpath(dt)
                if not upload_path.exists():
                    os.makedirs(upload_path.resolve().as_posix())

                for f in request.files.getlist('binfiles'):
                    file_path = upload_path.joinpath(secure_filename(f.filename))
                    f.save(file_path.resolve().as_posix())
                    files.append(file_path.resolve().as_posix())

                result, message = signalManager.actionApplicationBuild.emit(data, files)
                if result:
                    return response_result(ResponseCode.HTTP_SUCCESS, data=result)
                else:
                    return response_result(message)
            else:
                return response_result(ResponseCode.HTTP_INVAILD_REQUEST, msg="files can not be null")
        except Exception as e:
            traceback.print_exc()
            current_app.logger.error(e)
            return response_result(ResponseCode.HTTP_SERVER_ERROR)

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

    @jwt_required(locations=["headers"])
    def post(self):
        self.parser.add_argument("string", type=str, location="json", required=True)
        args = self.parser.parse_args()

        try:
            jwt = get_jwt_identity()
            logger.info(jwt)
            return response_result(ResponseCode.HTTP_SUCCESS, data=convert_string(args.string))
        except ValidationError as e:
            return response_result(ResponseCode.HTTP_INVAILD_REQUEST, data=e.messages)
        except Exception as e:
            data = None
            if hasattr(e, 'args'):
                data = e.args
            current_app.logger.error(e)
            return response_result(ResponseCode.HTTP_SERVER_ERROR, data=data)

class ObfuscatedCode(Resource):
    def __init__(self) -> None:
        super().__init__()
        self.parser = RequestParser()

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

        try:
            print(args)

            # fname = "./a.c"
            # target = os.sep.join(["out", fname])

            # if os.path.exists(fname):
            #     os.remove(fname)

            # if os.path.exists(target):
            #     os.remove(target)

            # with open(fname, "w+") as f:
            #     f.write(data['string'])

            # result = os.system("./opqcp {i} ./out".format(i=fname))
            # print(result)

            # with open(target) as f:
            #     result = f.read()

            # return result

            return response_result(ResponseCode.HTTP_SUCCESS)
        except ValidationError as e:
            return response_result(ResponseCode.HTTP_INVAILD_REQUEST, data=e.messages)
        except Exception as e:
            data = None
            if hasattr(e, 'args'):
                data = e.args
            current_app.logger.error(e)
            return response_result(ResponseCode.HTTP_SERVER_ERROR, data=data)
