from wechat_action.sql_models import DB
from settings import using_config
import tornado.log
import tornado.ioloop
import tornado.web
import json
from wechat_api.get_wechat_info import WechatApi
from wechat_action.login_ad import LogIn
from wechat_action import sql_tools
import threading
from web_module import user_action
from sqlalchemy import Table
import pickle

# TODO:需要添加上supervisor,来维护进程
# TODO:有时间需要对tornado进行改进
# TODO:需要有一套上线工具,来维持线上稳定

db = DB(config=using_config)
wechat_cookies_table = Table('wechat_cookies', db.metadata,
                             autoload=True, autoload_with=db.engine)
layout_typesetting_table = Table('layout_typesetting', db.metadata,
                                 autoload=True, autoload_with=db.engine)
ad_plan_typesetting_table = Table('ad_plan_typesetting', db.metadata,
                                  autoload=True, autoload_with=db.engine)


# 1.实现本机服务
# 2.实现线上docker-selenium服务

class BaseHandler(tornado.web.RequestHandler):
    def options(self):
        pass

    def set_default_headers(self):
        print('get in ')
        self.set_header('Access-Control-Allow-Origin', '*')
        self.set_header('Access-Control-Allow-Headers', '*')
        self.set_header('Access-Control-Max-Age', 1000)
        self.set_header('Content-type', '*')
        self.set_header('Access-Control-Allow-Methods', '*')


class create_ad_plan_remote(BaseHandler):
    # 1.批量创建计划
    # 返回创建计划是否已经开始
    def post(self):
        user_id = self.get_argument("user_id", None)
        ad_plan_name = self.get_argument("ad_plan_name", None)
        # wechat_json :[{'service_name':'one','wechat_name':''},{'service_name':'','wechat_name':''}]
        wechat_json = self.get_argument('wechat_json', None)
        log_ad, cookie_canuse = ad_human_info.refresh_wechat_cookies(self, user_id=user_id)
        threading.Thread(target=user_action.create_ad_plan,
                         args=(user_id, ad_plan_name, wechat_json, log_ad, db, cookie_canuse)).start()


class create_ad_plan_local(BaseHandler):
    def post(self):
        user_id = self.get_argument("user_id", None)
        ad_plan_typesetting = self.get_argument("plan_typesetting", None)
        ad_plan_name = self.get_argument("plan_name", None)
        print(user_id, ad_plan_typesetting, ad_plan_name)
        sql_session = db.DBSession()
        if user_id is None or ad_plan_name is None or ad_plan_typesetting is None:
            self.write({'status': {'msg': 'url parameter error', "RetCode": 400}})
            return
        # 落地页名字精确到毫秒,默认是全局唯一
        # TODO:检查一下plan--内容 有无问题-----和前端确定一下

        ad_plan_typesetting_info = {'user_id': user_id, 'name': ad_plan_name, 'typesetting': ad_plan_typesetting}
        ad_plan_typesetting_inserte = sql_tools.save_ad_plan_typesetting_info(
            ad_plan_typesetting_info=ad_plan_typesetting_info,
            table_ad_plan_typesetting=ad_plan_typesetting_table)
        sql_session.execute(ad_plan_typesetting_inserte)
        sql_session.commit()
        self.write({'status': {'msg': 'success', "RetCode": 200}})


class create_ad_layout_remote(BaseHandler):
    # 1.批量创建落地页
    def post(self):
        user_id = self.get_argument("user_id", None)
        layout_name = self.get_argument("layout_name", None)
        # wechat_json :[{'service_name':'one','wechat_name':''},{'service_name':'','wechat_name':''}]
        wechat_json = self.get_argument('wechat_json', None)
        log_ad, cookie_canuse = ad_human_info.refresh_wechat_cookies(self, user_id=user_id)
        threading.Thread(target=user_action.create_layout,
                         args=(user_id, layout_name, wechat_json, log_ad, db, cookie_canuse)).start()


class create_ad_layout_local(BaseHandler):
    def post(self):
        user_id = self.get_argument("user_id", None)
        layout_typesetting = self.get_argument("layout_typesetting", None)
        layout_name = self.get_argument("layout_name", None)
        print(user_id, layout_typesetting, layout_name)
        sql_session = db.DBSession()
        if user_id is None or layout_name is None or layout_typesetting is None:
            self.write({'status': {'msg': 'url parameter error', "RetCode": 400}})
            return
        # 落地页名字精确到毫秒,默认是全局唯一
        # TODO:检查一下layout--内容 有无问题-----和前端确定一下

        layout_typesetting_info = {'user_id': user_id, 'name': layout_name, 'typesetting': layout_typesetting}
        layout_typesetting_inserte = sql_tools.save_layout_typesetting_info(
            layout_typesetting_info=layout_typesetting_info,
            table_layout_typesetting=layout_typesetting_table)
        sql_session.execute(layout_typesetting_inserte)
        sql_session.commit()
        self.write({'status': {'msg': 'success', "RetCode": 200}})


# TODO:wechat_info,human_info 这两张表有空时需要进行对应改进
class ad_status(BaseHandler):
    def get(self):
        user_id = self.get_argument("user_id", None)
        if user_id is None:
            self.write({'status': {'msg': 'url parameter error', "RetCode": 400}})
            return
        sql_session = db.DBSession()

        lines = sql_tools.get_ad_status(sql_session=sql_session, user_id=user_id)
        result = []
        for line in lines:
            action_type, wechat_name, service_name, update_time, create_time, status = line
            result.append(
                {'action_type': json.loads(action_type), 'wechat_name': wechat_name, 'service_name': service_name,
                 'update_time': update_time.strftime("%Y-%m-%d %H:%M:%S"),
                 'create_time': create_time.strftime("%Y-%m-%d %H:%M:%S"), 'status': status})
        # result = json.loads(result)
        print(result)
        self.write({'status': {'msg': 'success', "RetCode": 200},
                    'ad_status_info': result})


class ad_human_info(BaseHandler):

    @staticmethod
    def refresh_wechat_cookies(tornado_web, user_id):
        # 1.返回二维码链接
        # ----1.查看cookie是否可用
        sql_session = db.DBSession()
        cookie_db = sql_tools.get_wechat_cookies(sql_session, user_id=user_id)

        # 进行登录操作
        log_ad = LogIn()

        # 使driver可以使用
        cookie_canuse = False
        if cookie_db:
            cookie_db = pickle.loads(cookie_db)

            # TODO:log 日志需要进行对应配置
            if not log_ad.wechat_cookies_check_alive(cookie_db):
                # cookie 不能使用
                wechat_code = log_ad.log_in()
                tornado_web.write({'status': {'msg': 'success', "RetCode": 200},
                                   'wechat_code': wechat_code})
                print('cookie can not use')
            else:
                # cookie 可以继续使用
                cookie_canuse = True
                log_ad.driver.get('https://a.weixin.qq.com/index.html')
                tornado_web.write({'status': {'msg': 'success', "RetCode": 200}})
        else:
            # cookie 不能使用
            wechat_code = log_ad.log_in()
            tornado_web.write({'status': {'msg': 'success', "RetCode": 200},
                               'wechat_code': wechat_code})
        return log_ad, cookie_canuse

    # 1.人群包获取
    def get(self):
        # TODO:添加分页

        # 0.是否刷新
        # 1.获取userid,以及是否刷新
        user_id = self.get_argument("user_id", None)
        human_package_name = self.get_argument('human_package_name', None)
        is_refresh = self.get_argument("is_refresh", None)
        wechat_name = self.get_argument('wechat_name', None)
        service_name = self.get_argument('service_name', None)
        print(user_id, is_refresh)
        if user_id is None or is_refresh is None or wechat_name is None or service_name is None:
            self.write({'status': {'msg': 'url parameter error', "RetCode": 400}})
            return
        sql_session = db.DBSession()
        # TODO:一个涉及到selenium-driver的请求-生命周期.----看一下tornado是怎么处理请求的生命周期
        if int(is_refresh) == 1:
            log_ad, cookie_canuse = self.refresh_wechat_cookies(self, user_id=user_id)
            threading.Thread(target=user_action.get_human_info,
                             args=(
                                 user_id, log_ad, db, cookie_canuse)).start()

        else:
            # 1.查看是否在刷新,
            #     在刷新中,
            #       返回正在刷新

            # -------不管上面逻辑让他们多刷新几次
            #     不在刷新
            #       返回对应数据
            # 2.获取userid对应数据
            result = sql_tools.get_human_info(sql_session=sql_session,
                                              service_name=service_name, wechat_name=wechat_name)
            print(result)
            result = json.loads(result)
            if human_package_name:
                result = [_ for _ in result if human_package_name in _['name']]
            result_ = []
            for i in range(len(result)):
                _ = result[i]
                _['id'] = i
                result_.append(_)
            self.write({'status': {'msg': 'success', "RetCode": 200},
                        'human_info': result})


class ad_wechat_info(BaseHandler):

    # 1.公众号相关信息获取
    def get(self):
        # TODO:添加分页,
        #  公众号,服务商,唯一id设计或者获取

        # 0.是否刷新
        # 1.获取userid,以及是否刷新
        user_id = self.get_argument("user_id", None)
        is_refresh = self.get_argument("is_refresh", None)
        print(user_id, is_refresh)
        if user_id is None or is_refresh is None:
            self.write({'status': {'msg': 'url parameter error', "RetCode": 400}})
            return
        sql_session = db.DBSession()
        # TODO:一个涉及到selenium-driver的请求-生命周期.----看一下tornado是怎么处理请求的生命周期
        if int(is_refresh) == 1:
            log_ad, cookie_canuse = ad_human_info.refresh_wechat_cookies(self, user_id=user_id)
            threading.Thread(target=user_action.get_human_info,
                             args=(
                                 user_id, log_ad, db, cookie_canuse)).start()
        else:
            # 1.查看是否在刷新,
            #     在刷新中,
            #       返回正在刷新

            # -------不管上面逻辑让他们多刷新几次
            #     不在刷新
            #       返回对应数据
            # 2.获取userid对应数据
            result = sql_tools.get_wechat_info(sql_session=sql_session, user_id=user_id)
            result_list = []
            for _ in result:
                service_name, wechat_name = _
                result_list.append({'service_name': service_name, 'wechat_name': wechat_name})
            print(result_list)
            self.write({'status': {'msg': 'success', "RetCode": 200},
                        'wechat_info': result_list})


def make_app():
    return tornado.web.Application([
        ("/create_ad_plan_local", create_ad_plan_local),
        ("/create_ad_layout_local", create_ad_layout_local),
        ("/create_ad_plan_remote", create_ad_plan_remote),
        ("/create_ad_layout_remote", create_ad_layout_remote),
        ("/ad_human_info", ad_human_info),
        ("/ad_wechat_info", ad_wechat_info),
        ("/ad_status", ad_status)
    ], debug=True, autoreload=True)


if __name__ == "__main__":
    tornado.log.LogFormatter()
    app = make_app()
    app.listen(8888)
    tornado.ioloop.IOLoop.current().start()