
import os
import sys
import json
import psutil
import platform
import tornado.web
import tornado.ioloop
import tornado.httpserver
import tornado.gen as gen
from loguru import logger
from script_client import func_map
from script_client import file_manage
from script_client import run_script
from script_client.const import config
from script_client.common.common_method import is_none,regist_app



class UploadHandler(tornado.web.RequestHandler):
    def get(self):
        self.render('upload.html')

    def post(self):
        post_date = {}
        try:
            post_date['app_code'] = self.get_body_argument('app_code')
            post_date['moniter_path'] = self.get_body_argument('moniter_path')
            post_date['script_file'] = self.request.files.get('file_obj', None)
            if is_none(post_date):
                self.write({'code': 0, 'msg': '都是必填的'})
                return
            if post_date['script_file'][0].filename.split('.')[-1] != 'py':
                self.write({'code': 0, 'msg': '只能上传.py文件'})
                return
            path = file_manage.find_file(app_code=post_date['app_code'], moniter_path=post_date['moniter_path'])
            if path == False:#不存在才注册
                regist_app_result = regist_app(post_date['app_code'], post_date['moniter_path'])
                if isinstance(regist_app_result, str):
                    self.write({'code': 0, 'msg': regist_app_result})
                    return
            save_file_result = file_manage.save_file(post_date)
            if isinstance(save_file_result, str):
                self.write({'code': 0, 'msg': save_file_result})
                return
            self.write({'code': 1, 'msg': '上传成功'})
        except Exception as e:
            self.write({'code': 0, 'msg': '上传失败：' + str(e)})


class ListenerHandler(tornado.web.RequestHandler):
    def set_default_headers(self):
        self.set_header('Content-Type', 'application/json')

    @gen.coroutine
    def post(self):
        try:
            data = json.loads(self.request.body)
            if not all((data['app_code'],data['moniter_path'],data['http_body'])):
                logger.error(f"有参数为空 data={data}")
                self.write({'code': 0, 'msg': f"有参数为空"})
                return
            if run_script.q.full():
                logger.warning(f"{config.local_ip}:{config.local_port}的队列已满")
                self.write({'code': 0, 'msg': f"{config.local_ip}:{config.local_port}的队列已满"})
                return
            fun_map = func_map.fm.get_map()
            if data['app_code'] in fun_map:
                if data['moniter_path'] in fun_map[data['app_code']]:
                    data['func_info'] = fun_map[data['app_code']][data['moniter_path']]
                    run_script.q.put(data)
                    logger.debug(f"q队列长度 = {run_script.q.qsize()}")
                    self.write({'code': 1, 'msg': 'success'})
                    return
            logger.info(f"没命中函数，现在注册的函数有{fun_map}")
            self.write({'code': 0, 'msg': '没命中函数'})
        except Exception as e:
            self.write({'code': 0, 'msg': f'{e}'})


def run_web_server():
    logger.info(f"启动webserver...")
    handlers =[
        (r"/", UploadHandler),
        (r"/receive_data", ListenerHandler),
    ]
    setting = dict(
        template_path=os.path.join(os.path.dirname(__file__), "templates"),
        static_path=os.path.join(os.path.dirname(__file__), "static"),
    )
    app = tornado.web.Application(handlers,**setting)
    httpServer = tornado.httpserver.HTTPServer(app)
    httpServer.bind(int(config.local_port))
    if (platform.system() != "Windows"):
        httpServer.start(1)
    else:#目前情况一个实例绝对够了
        httpServer.start(1)
    tornado.ioloop.IOLoop.current().start()

def _kill_terminate(p):
    # p.terminate()
    p.kill()


def stop_web_server():
    if os.path.exists('pid.log') == False:
        logger.info('没有pid.log')
        sys.exit(0)
    with open("pid.log", 'r') as fp:
        pid = int(fp.read())
    pidc = psutil.Process(pid)
    # ppid = pid.parent()
    # _kill_terminate(ppid)
    _kill_terminate(pidc)



if __name__ == "__main__":
    run_web_server()
