#!/usr/bin/env python
# -*- coding: utf_8 -*-
import os
import json
import datetime
import logging
import traceback
from flask import Blueprint, request
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.netdisc import AddSchema, DeleteSchema, QuerySchema, UpdateSchema
from utils import random_string

logger = logging.getLogger("netdiscApi")

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

FileStoragePath = os.path.normpath(os.path.join(config.get("UPLOAD_PATH"), config.get("NETDISC")))

if not os.path.exists(FileStoragePath):
    os.mkdir(FileStoragePath)

@netdisc_api.route("/add", methods=['POST'])
@validate_schema(AddSchema)
@Auth.auth_required
def add():
    try:
        binfile = request.files.get("binfile")

        information = {
            "name": "",
            "size": 0,
            "is_dir": False,
            "file_type": request.schema_data.get("file_type"),
            "parent_dir": request.schema_data.get("parent_dir"),
            "real_path": "",
        }

        if not binfile and not request.schema_data.get("file_type") and not request.schema_data.get("parent_dir") and not request.schema_data.get("name"):
            return response_result(ResponseCode.NO_DATA, msg="file can not be null")
        
        if os.path.normpath(information['parent_dir']).replace('\\', '/') == "/":
            result = { "real_path": FileStoragePath }
        else:
            t = os.path.normpath(information['parent_dir']).replace('\\', '/')
            b = os.path.basename(t)
            d = os.path.dirname(t)
            result, message = signalManager.actionGetNetDisc.emit({ "name": b, "parent_dir": d })
            if not result:
                return response_result(ResponseCode.NO_DATA_FOUND, msg="parent directory does not exists.")

        if not binfile:
            information['is_dir'] = True
            information['file_type'] = 'dir'
            information['name'] = request.schema_data.get("name")
            information['real_path'] = os.path.normpath(os.sep.join([result.get("real_path"), information['name']]))
            information['parent_dir'] = os.path.normpath(information['parent_dir']).replace('\\', '/')
            # os.path.relpath() 

            if os.path.exists(information['real_path']):
                return response_result(ResponseCode.EXISTS_ERROR, msg="File [%s] is existed! Please remove firstly" % information['real_path'])

            print(result.get("real_path"), information['name'])

            os.chdir(result.get("real_path")) # 切换目录
            os.mkdir(information['name']) # 创建目录
        else:
            information['name'] = binfile.filename
            saveFile = os.path.normpath(os.sep.join([result.get("real_path"), information['name']]))

            if os.path.exists(saveFile):
                return response_result(ResponseCode.EXISTS_ERROR, msg="File [%s] is existed! Please remove firstly" % saveFile)

            with open(saveFile, 'wb') as f:
                f.write(binfile.stream.read())

            information['size'] = os.path.getsize(saveFile)
            if not information['file_type']:
                information['file_type'] = os.path.splitext(information['name'])[-1]
            information['real_path'] = saveFile
            information['parent_dir'] = os.path.normpath(information['parent_dir']).replace('\\', '/')

        isSuccess, message = signalManager.actionAddNetDisc.emit(information)
        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))


@netdisc_api.route("/delete", methods=['POST'])
@validate_schema(DeleteSchema)
@Auth.auth_required
def delete():
    try:
        result, message = signalManager.actionDeleteNetDisc.emit(request.schema_data)
        if result:
            for f in result:
                if f[0]: os.rmdir(f[1])
                else: os.remove(f[1])
            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)


@netdisc_api.route("/get", methods=["POST"])
@validate_schema(QuerySchema)
@Auth.auth_required
def get():
    try:
        result, message = signalManager.actionGetNetDisc.emit(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))


@netdisc_api.route("/list", methods=['POST'])
@validate_schema(QuerySchema)
@Auth.auth_required
def get_list():
    try:
        result, count, message = signalManager.actionGetNetDiscList.emit(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)


@netdisc_api.route("/update/<uuid:id>", methods=['POST'])
@validate_schema(UpdateSchema)
@Auth.auth_required
def update(id):
    try:
        result, message = signalManager.actionUpdateNetDisc.emit(id, request.schema_data)
        if result:
            print(result)
            os.rename(result.get("src"), result.get("dst"))
            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)