from src.aws.s3 import ConfigBucket
from src.config.objects import FetchTargetObjects
from src.error.exceptions import FileNotFoundException, InvalidConfigException
from src.parser.json_parser import JsonParser
from src.system_var.constants import PRE_JP_NAME
from src.system_var.environments import (CRM_CONFIG_BUCKET,
                                         OBJECT_INFO_FILENAME,
                                         OBJECT_INFO_FOLDER)
from src.util.execute_datetime import ExecuteDateTime
from src.util.logger import logger_instance as logger


def prepare_data_fetch_process():
    """データ取得準備処理

    Raises:
        FileNotFoundException: S3上のファイルが存在しない場合
        InvalidConfigException: オブジェクト情報定義が不正だった場合

    Returns:
        fetch_target_objects : CRMオブジェクト情報インスタンス
        execute_datetime : 実行日時取得インスタンス
        process_result : 取得処理実行結果辞書オブジェクト
    """

    # ① データ取得準備処理の開始ログを出力する
    logger.info('I-PRE-01 データ取得準備処理を開始します')

    # ② 取得処理開始年月日時分秒を控える

    execute_datetime = ExecuteDateTime()

    logger.info(f'I-PRE-02 データ取得処理開始日時：{execute_datetime}')

    try:
        # ③ S3 設定ファイル保管用バケットから、CRM_取得オブジェクト情報ファイルを取得する
        object_info_file_s3_path = f's3://{CRM_CONFIG_BUCKET}/{OBJECT_INFO_FOLDER}/{OBJECT_INFO_FILENAME}'
        logger.info(
            f'I-PRE-03 CRM_取得オブジェクト情報ファイルの取得開始します ファイルパス：[{object_info_file_s3_path}]')

        config_bucket = ConfigBucket()
        object_info_file_str = config_bucket.get_object_info_file()

        logger.debug('D-PRE-04 CRM_取得オブジェクト情報ファイルの取得成功しました')

    except Exception as e:
        raise FileNotFoundException(
            'E-PRE-01', PRE_JP_NAME, f'CRM_取得オブジェクト情報ファイルが存在しません ファイル名：[{OBJECT_INFO_FILENAME}] エラー内容：[{e}]')

    try:
        # ④ CRM_取得オブジェクト情報ファイルをパースし、メモリ上に展開する
        logger.debug('D-PRE-05 CRM_取得オブジェクト情報ファイルをパースします')

        json_parser = JsonParser(object_info_file_str)
        object_info_file_dict = json_parser.parse()

        logger.debug('D-PRE-06 CRM_取得オブジェクト情報ファイルのパースに成功しました')

    except Exception as e:
        raise InvalidConfigException(
            'E-PRE-02', PRE_JP_NAME, f'CRM_取得オブジェクト情報ファイルのパースに失敗しました エラー内容：[{e}]')

    # ⑤ メモリ上のCRM_取得オブジェクト情報のキーobjectsの形式チェックを行う
    try:
        logger.debug('D-PRE-07 CRM_取得オブジェクト情報ファイルの形式チェックを開始します')

        fetch_target_objects = FetchTargetObjects(object_info_file_dict)

        logger.debug('D-PRE-08 CRM_取得オブジェクト情報ファイルの形式チェック 正常終了')

    except Exception as e:
        raise InvalidConfigException(
            'E-PRE-03', PRE_JP_NAME, f'CRM_取得オブジェクト情報ファイルの形式チェックに失敗しました ファイル名：[{OBJECT_INFO_FILENAME}] エラー内容：[{e}]')

    # ⑥ 処理結果出力用のマップを初期化
    process_result = {}

    # ⑦ データ取得準備処理の終了ログを出力する
    logger.info('I-PRE-09 データ取得準備処理を終了します')

    # ⑧ 次の処理へ移行する
    return (fetch_target_objects, execute_datetime, process_result)
