import logging
from queue import Queue
from func_timeout.exceptions import FunctionTimedOut
# useful for handling different item types with a single interface
from amazon_spider.db.mysql_db import del_mysql_asin


class TopAsinPipeline:
    def __init__(self, site):
        self.site = site
        self.q_dict = {"item_queue": Queue(), "error_queue": Queue()}
        self.num = 5
        self.save_num = 1

    @classmethod
    def from_crawler(cls, crawler):
        return cls(
            site=crawler.spider.site
        )

    def queue_consumer(self, q_size):
        sql_up_state = f"UPDATE `{self.site}_self_asin_top_hz` set state=(%s)  where asin=(%s) and site=(%s);"
        for k, v in self.q_dict.items():
            if q_size == "max":
                if v.qsize():
                    dates = [v.get() for i in range(0, v.qsize())]
                else:
                    dates = []
            else:
                if v.qsize() >= self.num:
                    dates = [v.get() for i in range(0, self.num)]
                else:
                    dates = []
            if k == "item_queue":
                if dates:
                    sql_up_data = f"UPDATE `{self.site}_self_asin_top_hz` set state=(%s), img_url=(%s), new_title=(%s), old_title=(%s)  where asin=(%s) and site=(%s);"
                    while True:
                        try:
                            if del_mysql_asin(sql_up_data, data=dates, site=self.site):
                                logging.info(f"修改asin状态3-----{len(dates)}---------{dates}")
                                break
                            else:
                                logging.info(f"修改asin状态3-失败----{len(dates)}---------{dates}")
                                continue
                        except FunctionTimedOut as e:
                            logging.info(f"修改asin状态3-超时{e}----{len(dates)}---------{dates}")
                            continue

            elif k == "error_queue":
                if dates:
                    if len(dates) == 1:
                        d = dates[0]
                    else:
                        d = dates
                    while True:
                        try:
                            if del_mysql_asin(sql_up_state, data=d, site=self.site):
                                logging.info(f"修改asin状态1-----{len(d)}---------{d}")
                                break
                            else:
                                logging.info(f"修改asin状态1-失败----{len(d)}---------{d}")
                                continue
                        except FunctionTimedOut as e:
                            logging.info(f"修改asin状态1-超时{e}----{len(d)}---------{d}")
                            continue

    def process_item(self, item, spider):
        if item.get("finish_spider"):
            print('等待时 将队列数据存储', {k: v.qsize() for k, v in self.q_dict.items()})
            self.queue_consumer("max")
        if item.get("error_asin"):
            self.q_dict.get("error_queue").put(item.get("asin"))
        elif item.get("inner_item"):
            # 因为是update 所以使用列表
            self.q_dict.get("item_queue").put(list(item["inner_item"].values()))
        self.queue_consumer("min")

    def close_spider(self, spider):
        print('爬虫结束，存储最后 数据', {k: v.qsize() for k, v in self.q_dict.items()})
        self.queue_consumer("max")