import json
import logging

import scrapy
from ApiSpiders.scrapy_selenium import SeleniumRequest
from ApiSpiders.utils.http_utils import http_get
from scrapy.utils.project import get_project_settings
from selenium.webdriver.firefox.options import Options


class ApiCommonSpider(scrapy.Spider):
    name = 'api_common'
    custom_settings = {
        'DOWNLOADER_MIDDLEWARES': {
            'ApiSpiders.scrapy_selenium.middlewares.SeleniumMiddleware': 1
        },
        'DOWNLOAD_DELAY': 3,
    }
    settings = get_project_settings()
    api_crawl_query_url = settings['API_RULES_QUERY_URL']
    api_crawl_query_url += '4'
    analyze_script = ''

    def __init__(self, params=None, *args, **kwargs):
        super(ApiCommonSpider, self).__init__(*args, **kwargs)
        self.driver_options = Options()
        self.driver_options.add_argument('-headless')
        json_params = json.loads(params)
        if 'job_id' in json_params:
            self.job_id = json_params['job_id']

    def start_requests(self):
        api_crawl_rsp = http_get(self.api_crawl_query_url)
        rsp_body = json.loads(api_crawl_rsp.text)
        if rsp_body['code'] != 200:
            logging.error('接口请求失败')
            return
        api_rules_info = rsp_body['content']
        login_type = api_rules_info['loginType']
        headers = {"Content-Type": "application/json"}

        if 'headers' in api_rules_info:
            api_headers = json.loads(api_rules_info['headers'])
            if len(api_headers) != 0:
                pass
            for key in api_headers:
                headers[key] = api_headers[key]
        # 判断是否需要登陆
        if login_type != 0:
            login_param = json.loads(api_rules_info['loginParam'])
            # 登录
            if login_type == 1:
                yield SeleniumRequest(url='https://www.baidu.com/', callback=self.next_requests,
                                      meta={"api_rules_info": api_rules_info, 'headers': headers})
            # 自定义cookie
            elif login_type == 2:
                headers['cookie'] = login_param['cookie']
                yield from self.send_request(api_rules_info, headers)
        else:
            yield from self.send_request(api_rules_info, headers)

    def next_requests(self, response):
        self.driver = response.request.meta['driver']
        api_rules_info = response.request.meta['api_rules_info']
        headers = response.request.meta['headers']
        login_param = json.loads(api_rules_info['loginParam'])
        login_script = api_rules_info['loginScript']
        exec(login_script)
        headers['cookie'] = self.driver.get_cookies()
        yield from self.send_request(api_rules_info, headers)

    def send_request(self, api_rules_info, headers):
        api_url = api_rules_info['apiUrl']
        request_mode = api_rules_info['requestMode']
        self.analyze_script = api_rules_info['analyzeScript']
        # GET请求
        if request_mode == 'GET':
            # 拼接自定义params参数
            if 'params' in api_rules_info:
                params = json.loads(api_rules_info['params'])
                if len(params) != 0:
                    api_url += '?'
                    for key in params:
                        api_url += f'{key}={params[key]}&'
            yield scrapy.Request(url=api_url, method=request_mode, headers=headers, callback=self.parse)
        # POST请求
        else:
            data_body = api_rules_info['dataBody']
            if '{page_index}' in data_body:
                for index in range(1, 10):
                    yield scrapy.Request(url=api_url, method=request_mode, headers=headers,
                                         body=data_body.replace('"{page_index}"', str(index)),
                                         callback=self.parse)
            else:
                yield scrapy.Request(url=api_url, method=request_mode, headers=headers, body=data_body,
                                     callback=self.parse)

    def parse(self, response, **kwargs):
        exec(self.analyze_script)
