import csv
import os
import re
from datetime import datetime

import mysql.connector
import requests
from bs4 import BeautifulSoup

from common import upload_to_minio, save_to_db_import_record, db_config, get_md5, fetch_db_import_record

# 设置下载目录
download_dir = 'downloaded_files/ESA'
os.makedirs(download_dir, exist_ok=True)

# 获取网页内容
url = 'https://esarad.esa.int/'


def scrape():
    esa_connection = mysql.connector.connect(**db_config)
    try:
        response = requests.get(url)

        # 确保请求成功
        if response.status_code == 200:
            # 解析网页内容
            soup = BeautifulSoup(response.content, 'html.parser')

            # 找到所有表格
            tables = soup.find_all('table')

            # 提取第一个表格的内容
            tab_content = tables[0].find_all('tr')[2:]
            tab_content.reverse()
            for row in tab_content:  # 跳过标题行
                cells = row.find_all(['td', 'th'])
                table_id = get_md5('ESA-' + cells[0].get_text(strip=True))
                # count = fetch_db_import_record(esa_connection, (table_id,))
                # if count > 0:
                #     continue
                folder_name = table_id  # cells[1].get_text(strip=True)  # 第2列
                file_id = cells[0].get_text(strip=True)  # 第1列
                download_url = f'https://esarad.esa.int/?id={file_id}&handler=DownloadDb'

                # 创建文件夹
                folder_path = os.path.join(download_dir, folder_name)
                os.makedirs(folder_path, exist_ok=True)

                # 下载文件并获取文件名
                file_response = requests.get(download_url)
                if file_response and file_response.status_code == 200:
                    # 从响应头获取文件名
                    content_disposition = file_response.headers.get('Content-Disposition')
                    filename = ''
                    if content_disposition:
                        match = re.search(r'filename="([^"]+)"', content_disposition)
                        if match:
                            filename = match.group(1)

                    if not filename:  # 如果没有找到，则使用默认文件名
                        filename = f'{file_id}.pdf'

                    file_path = os.path.join(folder_path, filename)
                    if not os.path.exists(file_path):
                        with open(file_path, 'wb') as f:
                            f.write(file_response.content)
                        print(f'ESA Downloaded: {file_path}')
                    else:
                        print(f'file exist: {file_path}')

                    # 创建 CSV 文件
                    csv_file_path = os.path.join(folder_path, 'data.csv')
                    with open(csv_file_path, 'w', newline='', encoding='utf-8') as csvfile:
                        writer = csv.writer(csvfile)
                        # 写入标题行
                        writer.writerow([
                            '序号', '试验对象类型', '试验开始日期', '试验结束日期', '试验对象名称',
                            '试验对象型号', '试验对象数量', '试验性质', '试验目的', '装置名称',
                            '数据提供单位', '试验委托单位', '失效判据', '失效数量', '试验结果描述',
                            '成果', '来源项目名称', '来源项目类型', '分类', '元器件名称',
                            '元器件型号', '元器件批号', '生产单位', '是否国产', '元器件成熟度',
                            '晶圆材料', '晶圆批号', '封装材料', '封装技术', '是否倒装',
                            '制造工艺', '工艺特征尺寸', '工艺平台', '工艺代号', '工艺版本',
                            '质量等级', '加固措施', '工作原理', '供货能力', '应用经历',
                            '规范手册', '器件图片', '电子系统分类', '电子系统名称', '电子系统型号',
                            '生产单位', '电子系统功能', '电子系统加固措施', '电子系统图片', '材料名称',
                            '材料型号', '材料组分', '材料用途', '材料生产单位', '材料物理结构',
                            '材料使用经历', '辐照试验大纲', '大纲审核专家类别', '辐照试验所依据的标准规范',
                            '试验步骤（过程）描述', '辐照过程是否加电', '直流偏置条件描述', '交流偏置条件描述',
                            '时钟频率', '测试图形', '其他偏置条件', '辐照偏置原理图', '测试方式',
                            '测试原理图', '试验用仪器名称', '试验用仪器型号', '试验用仪器生产厂家',
                            '试验用仪器检定证书', '试验用软件名称', '试验用软件开发单位',
                            '试验用软件版本号', '试验现场照片', '测试人员姓名', '测试人员单位',
                            '测试人员电话', '装置运行人员', '第三方人员', '第三方人员单位',
                            '第三方人员电话', '其他需要说明的事项', '是否采用铅铝屏蔽', '剂量率',
                            '总剂量', '剂量等效材料', '试验对象编号', '测试参数名称',
                            '测试参数单位', '测试参数结果', '是否为加速试验后数据', '是否为退火数据',
                            '退火温度', '退火时间', '原始数据', '数据处理方法', '其他需要说明的事项'
                        ])

                        # 写入数据行并保存到数据库
                        data_row = [
                            file_id,  # 序号
                            '',  # 试验对象类型（可以根据需要填充）
                            cells[11].get_text(strip=True),  # 试验开始日期（第12列）
                            '',  # 试验结束日期（可以根据需要填充）
                            '',  # 试验对象名称（可以根据需要填充）
                            cells[1].get_text(strip=True),  # 试验对象型号（第2列）
                            '',  # 试验对象数量（可以根据需要填充）
                            cells[5].get_text(strip=True),  # 试验性质（第6列）
                            '',  # 试验目的（可以根据需要填充）
                            '',  # 装置名称（可以根据需要填充）
                            '',  # 数据提供单位（可以根据需要填充）
                            '',  # 试验委托单位（可以根据需要填充）
                            '',  # 失效判据（可以根据需要填充）
                            '',  # 失效数量（可以根据需要填充）
                            '',  # 试验结果描述（可以根据需要填充）
                            '',  # 成果（可以根据需要填充）
                            '',  # 来源项目名称（可以根据需要填充）
                            '',  # 来源项目类型（可以根据需要填充）
                            '',  # 分类（可以根据需要填充）
                            '',  # 元器件名称（可以根据需要填充）
                            '',  # 元器件型号（可以根据需要填充）
                            '',  # 元器件批号（可以根据需要填充）
                            cells[3].get_text(strip=True),  # 生产单位（第4列）
                            '',  # 是否国产（可以根据需要填充）
                            '',  # 元器件成熟度（可以根据需要填充）
                            '',  # 晶圆材料（可以根据需要填充）
                            '',  # 晶圆批号（可以根据需要填充）
                            '',  # 封装材料（可以根据需要填充）
                            '',  # 封装技术（可以根据需要填充）
                            '',  # 是否倒装（可以根据需要填充）
                            '',  # 制造工艺（可以根据需要填充）
                            '',  # 工艺特征尺寸（可以根据需要填充）
                            '',  # 工艺平台（可以根据需要填充）
                            '',  # 工艺代号（可以根据需要填充）
                            '',  # 工艺版本（可以根据需要填充）
                            '',  # 质量等级（可以根据需要填充）
                            '',  # 加固措施（可以根据需要填充）
                            '',  # 工作原理（可以根据需要填充）
                            '',  # 供货能力（可以根据需要填充）
                            '',  # 应用经历（可以根据需要填充）
                            '',  # 规范手册（可以根据需要填充）
                            '',  # 器件图片（可以根据需要填充）
                            '',  # 电子系统分类（可以根据需要填充）
                            '',  # 电子系统名称（可以根据需要填充）
                            '',  # 电子系统型号（可以根据需要填充）
                            '',  # 生产单位（可以根据需要填充）
                            '',  # 电子系统功能（可以根据需要填充）
                            '',  # 电子系统加固措施（可以根据需要填充）
                            '',  # 电子系统图片（可以根据需要填充）
                            '',  # 材料名称（可以根据需要填充）
                            '',  # 材料型号（可以根据需要填充）
                            '',  # 材料组分（可以根据需要填充）
                            '',  # 材料用途（可以根据需要填充）
                            '',  # 材料生产单位（可以根据需要填充）
                            '',  # 材料物理结构（可以根据需要填充）
                            '',  # 材料使用经历（可以根据需要填充）
                            '',  # 辐照试验大纲（可以根据需要填充）
                            '',  # 大纲审核专家类别（可以根据需要填充）
                            '',  # 辐照试验所依据的标准规范（可以根据需要填充）
                            '',  # 试验步骤（过程）描述（可以根据需要填充）
                            '',  # 辐照过程是否加电（可以根据需要填充）
                            '',  # 直流偏置条件描述（可以根据需要填充）
                            '',  # 交流偏置条件描述（可以根据需要填充）
                            '',  # 时钟频率（可以根据需要填充）
                            '',  # 测试图形（可以根据需要填充）
                            '',  # 其他偏置条件（可以根据需要填充）
                            '',  # 辐照偏置原理图（可以根据需要填充）
                            '',  # 测试方式（可以根据需要填充）
                            '',  # 测试原理图（可以根据需要填充）
                            '',  # 试验用仪器名称（可以根据需要填充）
                            '',  # 试验用仪器型号（可以根据需要填充）
                            '',  # 试验用仪器生产厂家（可以根据需要填充）
                            '',  # 试验用仪器检定证书（可以根据需要填充）
                            '',  # 试验用软件名称（可以根据需要填充）
                            '',  # 试验用软件开发单位（可以根据需要填充）
                            '',  # 试验用软件版本号（可以根据需要填充）
                            '',  # 试验现场照片（可以根据需要填充）
                            '',  # 测试人员姓名（可以根据需要填充）
                            '',  # 测试人员单位（可以根据需要填充）
                            '',  # 测试人员电话（可以根据需要填充）
                            '',  # 装置运行人员（可以根据需要填充）
                            '',  # 第三方人员（可以根据需要填充）
                            '',  # 第三方人员单位（可以根据需要填充）
                            '',  # 第三方人员电话（可以根据需要填充）
                            '',  # 其他需要说明的事项（可以根据需要填充）
                            '',  # 是否采用铅铝屏蔽（可以根据需要填充）
                            '',  # 剂量率（可以根据需要填充）
                            '',  # 总剂量（可以根据需要填充）
                            '',  # 剂量等效材料（可以根据需要填充）
                            '',  # 试验对象编号（可以根据需要填充）
                            '',  # 测试参数名称（可以根据需要填充）
                            '',  # 测试参数单位（可以根据需要填充）
                            '',  # 测试参数结果（可以根据需要填充）
                            '',  # 是否为加速试验后数据（可以根据需要填充）
                            '',  # 是否为退火数据（可以根据需要填充）
                            '',  # 退火温度（可以根据需要填充）
                            '',  # 退火时间（可以根据需要填充）
                            '',  # 原始数据（可以根据需要填充）
                            '',  # 数据处理方法（可以根据需要填充）
                            ''  # 其他需要说明的事项（可以根据需要填充）
                        ]
                        writer.writerow(data_row)
                        # (`id`, `create_by`, `create_time`, `update_by`, `update_time`, `sys_org_code`, `device_type`,
                        # `device_name`, `device_mode`, `device_function`, `device_batch`, `manufacturer`, `experiment_date`, `data_source`, `experiment_user`, `total_count`, `file_list`)

                    print(f'CSV created and data saved to MySQL: {csv_file_path}')
                else:
                    print(f'Failed to download: {download_url}')

                upload_ids = upload_to_minio(esa_connection, folder_path, 'ESA')
                origin_data = ','.join([c.get_text(strip=True) for c in cells])
                data_db = [table_id, 'Crawler', datetime.now(), None, None, None,
                           cells[5].get_text(strip=True),
                           cells[1].get_text(strip=True), cells[1].get_text(strip=True),
                           cells[8].get_text(strip=True),
                           cells[7].get_text(strip=True), cells[2].get_text(strip=True),
                           cells[11].get_text(strip=True),
                           'ESA', None, None, str(upload_ids), origin_data
                           ]
                save_to_db_import_record(esa_connection, data_db)
        else:
            print(f'Error: {response.status_code}')
    except Exception as e:
        print(e)
    finally:
        # 关闭游标和连接
        esa_connection.close()
