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

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

from app import config, signalManager
from fullstack.login import Auth
from fullstack.response import ResponseCode, response_result
from fullstack.validation import validate_schema
from schema.api import UpdatePasswordSchema, ApplicationBuildSchema, ConvertString

logger = logging.getLogger(__name__)

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

def stopApp():
    fpath = os.sep.join([os.getcwd(), "restart.json"])
    with open(fpath, "w+") as f:
        ret = json.loads(f.read())
        ret["count"] = ret["count"] + 1
        f.write(json.dumps(ret, indent=4))
    return ret

@api.route("/evm", methods=['GET','POST'])
def hello_evm():
    def check(p):
        if hasattr(request, p):
            return getattr(request, p)
        else:
            return None
    
    print(request.method)
    print(request.headers)
    print(request.data)
    print(request.stream.read())
    print(request.get_data())

    if request.method == "GET":
        result = { "args": request.args }
    else:
        result = {
            'args': check('args'),
            'json': check('json'),
            'data': check('values'),
            'form': check('form')
        }
    
    return json.dumps(result)

@api.route("/store", methods=['GET', 'POST'])
def get_store():
    result = {}
    with open("./apiData.json", "r", encoding="utf-8") as f:
        result = json.loads(f.read())

    logger.info(request.args)
    # logger.info(request.query_string)
    if request.args and request.args.get("category"):
        res = []
        for item in result.get("appList", []):
            if item.get("category") == request.args.get("category"):
                res.append(item)
        result["appList"] = res

    result = {
        'appList': result["appList"],
        'categoryList': result["categoryList"]
    }

    return response_result(ResponseCode.OK, data=result)

@api.route("/store/app/<uuid>", methods=['GET', 'POST'])
def get_store_app(uuid):
    logger.info(uuid)
    result = {}
    with open("./apiData.json", "r", encoding="utf-8") as f:
        result = json.loads(f.read())

    res = {}
    for item in result.get("appList", []):
        if item.get("uuid") == uuid:
            res = item
            break

    return response_result(ResponseCode.OK, data=res)

@api.route("/store/appInfo/<uuid>", methods=['GET', 'POST'])
def get_app_info(uuid):
    result = {}
    with open("./apiData.json", "r", encoding="utf-8") as f:
        result = json.loads(f.read())

    res = None
    for item in result.get("downloadList", []):
        if item.get("apkId") == uuid:
            res = item
            break

    print(res)
    return response_result(ResponseCode.OK, data=res)

@api.route("/store/downloadEpk/<uuid>", methods=['GET', 'POST'])
def download_epk(uuid):
    # 这里要做一些业务处理,根据应用ID和版本号,判断是否有新的应用更新
    result = {}
    with open("./apiData.json", "r", encoding="utf-8") as f:
        result = json.loads(f.read())

    res = {}
    for item in result.get("downloadList", []):
        if item.get("apkId") == uuid:
            res.update(item)
            break
    res.update({
        'status': 0,
        'time': int(time.time())
    })
    print(res)
    return response_result(ResponseCode.OK, data=res)

@api.route("/opqcp", methods=['POST'])
def action_opqcp():
    params = request.json
    result, message = signalManager.actionOpqcp.emit(params)
    print(result)

    return response_result(ResponseCode.OK, msg=message)

@api.route("/monitor", methods=['GET', 'POST'])
def action_monitor():
    print(request.json)
    print(request.data)
    print(request.form)
    print(type(request.json))
    
    return response_result(ResponseCode.OK)

@api.route("/updatePassword", methods=['POST'])
@validate_schema(UpdatePasswordSchema)
@Auth.auth_required
def update_password():
    result, message = signalManager.actionUpdatePassword.emit(request.current_user.get("id"), request.schema_data)
    if result:
        return response_result(ResponseCode.OK, data=result, msg=message)
    else:
        return response_result(ResponseCode.NOTHING_CHANGE, msg=message)

@api.route("/upload", methods=['POST']) # 上传文件
def upload_file():
    try:
        result = None

        binfile = request.files.get("binfile")
        if not binfile:
            return response_result(ResponseCode.REQUEST_ERROR, msg="upload field name error")

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

        dtNowString = datetime.now().strftime("%Y%m%d%H%M%S%f")

        # 文件名构成:文件名_时间日期.文件后缀
        filename = os.path.splitext(obj['filename'])[0] + "_{}".format(dtNowString) + os.path.splitext(obj['filename'])[-1]

        # 获取相对路径
        relative_path = os.sep.join([config.get("TEMP_DIR"), dtNowString])

        # 获取最终存储的绝对路径
        savePath = os.path.normpath(os.sep.join([config.get("UPLOAD_PATH"), relative_path]))

        # 获取最终存储的文件路径
        saveFile = os.path.normpath(os.sep.join([savePath, filename]))

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

        with open(saveFile, 'wb') as f: # 保存文件
            f.write(obj['content'])

        result = {
            "uuid": str(uuid.uuid4()), # 附件唯一编号
            "filename": obj['filename'], # 附件名称
            "filesize": os.path.getsize(saveFile), # 附件大小
            "filepath": os.sep.join([relative_path, filename]).replace("\\", "/"), # 附件存储路径
        }

        return response_result(ResponseCode.OK, data=result, msg="upload file [%s] successfully!" % obj['filename'])
    except Exception as e:
        traceback.print_exc()
        logger.error(str(e))
        return response_result(ResponseCode.SERVER_ERROR, msg=str(e))

@api.route("/system/updateDatabase", methods=['GET'])
def update_db():
    result = []
    for index in range(16):
        print(index)
        result.append(str(uuid.uuid1()))

    # conn = sqlite3.connect('./app-store.db')
    # cur = conn.cursor()
    # update_sql = """update test set name = 'noname' where id = ?"""
    # x = (1, )
    # cur.execute(update_sql, x)
    # # commit()提交事务
    # conn.commit()
    # # 关闭游标
    # cur.close()
    # # 关闭连接
    # conn.close()

    return response_result(ResponseCode.OK, data=result)

@api.route("/system/convertString", methods=['POST'])
@validate_schema(ConvertString)
def convert_string():
    result = signalManager.actionGetConvertString.emit(request.schema_data)
    return response_result(ResponseCode.OK, data=result)

@api.route("/application/build", methods=["post"])
@validate_schema(ApplicationBuildSchema)
def application_build():
    try:
        if request.method == 'POST' and 'binfiles' in request.files:
            files = []
            data = request.schema_data
            dt = datetime.now().strftime("%Y%m%d%H%M%S")
            upload_path = os.sep.join([config["UPLOAD_PATH"], config["TEMP_DIR"], str(data['access_key']), dt])
            if not os.path.exists(upload_path):
                os.makedirs(upload_path)
            for f in request.files.getlist('binfiles'):
                filename = secure_filename(f.filename)
                file_path = os.sep.join([upload_path, filename])
                f.save(file_path)
                files.append(file_path)

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