from src.logging.get_logger import get_logger
from src.batch.jskult_archive_manager import JskultArchiveManager
from src.aws.s3 import JskultArchiveBucket
import os.path as path
from datetime import timedelta
import tempfile
import csv
import zipfile


logger = get_logger("実消化_過去データアーカイブ処理")

def exec():
    """実消化_過去データアーカイブ処理"""
    try:
        logger.info("処理開始:実消化_過去データアーカイブ処理")
        jskult_archive_manager = JskultArchiveManager()
        # アーカイブ管理テーブルから対象テーブル、条件項目、条件年月、実行間隔（月）、前回条件年月、保存先を取得
        jskult_archive_manage_data_list = jskult_archive_manager.get_archive_manage()

        # 取得したレコード分繰り返す
        for jskult_archive_manage_data in jskult_archive_manage_data_list:
            # 対象テーブルで条件項目が条件年月以前のデータを取得
            archive_data = jskult_archive_manager.get_archive_data(jskult_archive_manage_data["target_table"], jskult_archive_manage_data["filter_column"], jskult_archive_manage_data["filter_date"])
            # 取得データが0件の場合、スキップする
            if not archive_data:
                logger.info(f"アーカイブ対象データがありませんでした。対象テーブル：{jskult_archive_manage_data['target_table']} 条件年月：{jskult_archive_manage_data['filter_date']}")
                continue

            # 一時フォルダ作成
            with tempfile.TemporaryDirectory() as temporary_dir: 
                # 取得したデータをCSVに出力
                day_after_prev_filter_date = jskult_archive_manage_data["prev_filter_date"] + timedelta(days=1)
                file_name = f'{jskult_archive_manage_data["target_table"]}_{day_after_prev_filter_date.strftime('%Y%m%d')}_{jskult_archive_manage_data["filter_date"].strftime('%Y%m%d')}'
                csv_file_path = path.join(temporary_dir, f"{file_name}.csv")
                headers = archive_data[0].keys()
                with open(csv_file_path, 'w', newline='') as file:
                    writer = csv.DictWriter(file, fieldnames=headers, quoting=csv.QUOTE_ALL)
                    writer.writeheader()
                    writer.writerows(archive_data)
                    logger.info(f"CSVファイル作成に成功しました。{file_name}.csv")
                
                # 作成したCSVをzip形式に圧縮
                zip_file_path = path.join(temporary_dir, f"{file_name}.zip")
                with zipfile.ZipFile(zip_file_path, 'w', zipfile.ZIP_DEFLATED) as zipf:
                    zipf.write(csv_file_path)
                logger.info(f"zip形式への圧縮に成功しました。{file_name}.zip")

                # 圧縮したCSVを保存先へアップロード
                archive_bucket = JskultArchiveBucket()
                upload_file_path = archive_bucket.upload_archive_zip_file(f"{file_name}.zip", zip_file_path, jskult_archive_manage_data["archive_storage"])
                logger.info(f"{upload_file_path}へのアップロードに成功しました。")

                # アーカイブしたデータをDBから削除
                jskult_archive_manager.delete_archive_data(jskult_archive_manage_data["target_table"], jskult_archive_manage_data["filter_column"], jskult_archive_manage_data["filter_date"])
                logger.info(f"アーカイブしたデータのDBから削除に成功しました。対象テーブル：{jskult_archive_manage_data['target_table']} 条件年月：{jskult_archive_manage_data['filter_date']}")

                # 次回に向けてアーカイブ管理テーブルを更新する
                jskult_archive_manager.update_archive_manage(jskult_archive_manage_data["target_table"])
                logger.info(f"アーカイブ管理テーブルの更新に成功しました。対象テーブル：{jskult_archive_manage_data['target_table']}")
        logger.info("処理終了:実消化_過去データアーカイブ処理")
    except Exception as e:
        logger.exception(f"異常終了:実消化_過去データアーカイブ処理 {e}")