# -*- coding: utf-8 -*-
"""
@File: services.py
@Date: 2020-09-14
@author: A2TEC
@section MODIFYINFO 수정정보
- 수정자/수정일   : 수정내역
- 2022-01-14/hsj100@a2tec.co.kr : refactoring
@brief: services api
"""

import requests, json, traceback, os, shutil
from fastapi import APIRouter, Depends, Body
from starlette.requests import Request
from typing import Annotated, List

from main_rest.app.common import consts
from main_rest.app import models as M
from main_rest.app.utils.date_utils import D
from main_rest.app.utils.parsing_utils import image_to_base64_string,save_base64_as_image_file
from custom_logger.main_log import main_logger as LOG

# from custom_apps.bingimagecreator.utils import DallEArgument,dalle3_generate_image
# from custom_apps.bingart.bingart import BingArtGenerator
# from custom_apps.imagen.custom_imagen import imagen_generate_image, imagen_generate_image_path, imagen_generate_temp_image_path
from custom_apps.utils import cookie_manager
from custom_apps.gemini.main import gemini_image
from main_rest.app.utils.parsing_utils import download_range
from utils.custom_sftp import sftp_client
from config import rest_config
from const import TEMP_FOLDER

router = APIRouter(prefix="/services")

# @router.post("/bing/cookie/set", summary="bing 관련 쿠키 set", response_model=M.BingCookieSetRes)
# async def bing_cookie_set(request: Request, request_body_info: M.BingCookieSetReq):
#     """
#     ## Bing cookie set
#     > 쿠키정보 set
    
#     ## 정보
#     > cookie 값이 빈 값일경우 쿠키정보를 set 하지 않고 현재 쿠키값 return 함
#     > cookie 값이 정상 쿠키 인지는 확인안함
    
#     """
#     response = M.BingCookieSetRes()
#     try:
#         if len(request_body_info.cookie) == 0:
#             pass
#         else:
#             cookie_manager.set_cookie(request_body_info.cookie)
        
#         return response.set_message(current_cookie=cookie_manager.get_cookie())
       
#     except Exception as e:
#         LOG.error(traceback.format_exc())
#         return response.set_error(e,current_cookie=cookie_manager.get_cookie())


# @router.post("/imageGenerate/bingimg", summary="이미지 생성(AI) - bing image generator (DALL-E 3)", response_model=M.ImageGenerateRes)
# async def bing_img_generate(request: Request, request_body_info: M.ImageGenerateReq):
#     """
#     ## 이미지 생성(AI) - bing image generator (DALL-E 3)
#     > bing image generator를 이용하여 이미지 생성
    
#     ### Requriements

    
#     ## 정보
#     > 오류 발생시 오류 발생한 파일은 에러 메세지에만 남기고 저장은 안함
    
#     """
#     response = M.ImageGenerateRes()
#     try:
#         if not download_range(request_body_info.downloadCount):
#             raise Exception(f"downloadCount is 1~4 (current value = {request_body_info.downloadCount})")


#         args = DallEArgument(
#             prompt=request_body_info.prompt,
#             download_count=request_body_info.downloadCount
#             )       
        
#         info = dalle3_generate_image(args)
        
#         if info.get_error_messages():
#             error_message = f"파일생성 error: {info.get_error_messages()}"
#             LOG.error(error_message)
#             return response.set_error(error=error_message, img_len=info.get_counter())
        
#         return response.set_message(img_len=info.get_counter())
       
#     except Exception as e:
#         LOG.error(traceback.format_exc())
#         return response.set_error(e)
    
# @router.post("/imageGenerate/bingart", summary="이미지 생성(AI) - bing art (DALL-E 3)", response_model=M.ImageGenerateRes)
# async def bing_art(request: Request, request_body_info: M.ImageGenerateReq):
#     """
#     ## 이미지 생성(AI) - bing art (DALL-E 3)
#     > bing art를 이용하여 이미지 생성
    
#     ### Requriements
    
    
#     ## 정보
#     > 오류 발생시 오류 발생한 파일은 에러 메세지에만 남기고 저장은 안함
#     > *동작 안함.
    
#     """
#     response = M.ImageGenerateRes()
#     try:
#         if not download_range(request_body_info.downloadCount):
#             raise Exception(f"downloadCount is 1~4 (current value = {request_body_info.downloadCount})")

#         bing_art = BingArtGenerator()
        
#         info = bing_art.get_images(prompt=request_body_info.prompt,image_len=request_body_info.downloadCount)
        
#         return response.set_message(img_len=info)
       
#     except Exception as e:
#         LOG.error(traceback.format_exc())
#         return response.set_error(e)
    
# @router.post("/imageGenerate/imagen", summary="이미지 생성(AI) - imagen", response_model=M.ResponseBase)
# async def imagen(request: Request, request_body_info: M.ImageGenerateReq):
#     """
#     ## 이미지 생성(AI) - imagen
#     > imagen AI를 이용하여 이미지 생성
#     """
#     # imagen 사용중단 gemini로 변경
    
#     response = M.ResponseBase()
#     try:
#         # NOTE(JWKIM) : imagen 사용 중단
#         # img_length = imagen_generate_image(prompt=request_body_info.prompt,
#         #                       download_count=request_body_info.downloadCount
#         #                       )
        # temp_image_path = gemini_image(request_body_info.prompt)
        
#         if rest_config.config != 'release':
#             _remote_folder = os.path.join(rest_config.remote_folder,"imagen")
#             # remote save
#             sftp_client.remote_copy_data(
#                 temp_image_path, 
#                 os.path.join(_remote_folder,f"imagen_{request_body_info.prompt}_{1}_{D.date_file_name()}.png"))
#         else:
#             _local_forder = os.path.join(rest_config.local_folder,"image_generate","imagen")
#             os.makedirs(_local_forder,exist_ok=True)
#             shutil.copy(temp_image_path, os.path.join(_local_forder,f"imagen_{request_body_info.prompt}_{1}_{D.date_file_name()}.png"))
        
#         # Clean up temporary files
#         if 'temp_image_path' in locals():
#             if os.path.exists(temp_image_path):
#                 os.remove(temp_image_path)
#                 del temp_image_path
        
#         return response.set_message()
    
#     except Exception as e:
#         LOG.error(traceback.format_exc())
        
#         # Clean up temporary files
#         if 'query_image_path' in locals():
#             if os.path.exists(query_image_path):
#                 os.remove(query_image_path)
#                 del query_image_path
        
#         return response.set_error(error=e)
    
# @router.post("/imageGenerate/imagen/data", summary="이미지 생성(AI) - imagen(data)", response_model=M.ImageGenerateDataRes)
# async def imagen_data(request: Request, request_body_info: M.ImageGenerateReq):
#     """
#     ## 이미지 생성(AI) - imagen
#     > imagen AI를 이용하여 이미지 데이터생성
#     """
#     # imagen 사용중단 gemini로 변경
    
#     response = M.ImageGenerateDataRes()
#     try:
#         # NOTE(JWKIM) : imagen 사용 중단
#         # img_length = imagen_generate_image(prompt=request_body_info.prompt,
#         #                       download_count=request_body_info.downloadCount
#         #                       )
#         temp_image_path = gemini_image(request_body_info.prompt)
        
#         b64data = image_to_base64_string(temp_image_path)
        
#         # Clean up temporary files
#         if 'temp_image_path' in locals():
#             if os.path.exists(temp_image_path):
#                 os.remove(temp_image_path)
#                 del temp_image_path
        
#         return response.set_message(b64data)
    
#     except Exception as e:
#         LOG.error(traceback.format_exc())
        
#         # Clean up temporary files
#         if 'query_image_path' in locals():
#             if os.path.exists(query_image_path):
#                 os.remove(query_image_path)
#                 del query_image_path
        
#         return response.set_error(error=e)

# @router.post("/vectorImageSearch/imagenet/imageGenerate/imagen", summary="벡터 이미지 검색(imagenet) - imagen", response_model=M.ResponseBase)
# async def vactor_imagenet(request: Request, request_body_info: M.vectorImageSearchReq):
#     """
#     ## 벡터 이미지 검색 - imagen
#     > imagen AI를 이용하여 이미지 생성 후 vector 검색
    
#     ### Requriements
#     > - googlecli 설치(https://cloud.google.com/sdk/docs/install?hl=ko#linux)
#     > - const.py 에 지정한 OUTPUT_FOLDER 하위에 imagen 폴더가 있어야함.
    
#     """
#     # NOTE(JWKIM) : GPU 메모리 이슈로 사용 중단
#     response = M.ResponseBase()
#     try:       
#         if request_body_info.indexType not in [M.IndexType.hnsw, M.IndexType.l2]:
#             raise Exception(f"indexType is hnsw or l2 (current value = {request_body_info.indexType})")
        
#         _temp_folder = f"{request_body_info.prompt}_{D.date_file_name()}"
        
#         # img_path = imagen_generate_image_path(image_prompt=request_body_info.prompt) #imagen
#         img_path = gemini_image(request_body_info.prompt, os.path.join(TEMP_FOLDER, _temp_folder)) #gemini
        
#         vector_request_data = {'query_image_path' : img_path,
#                                'index_type' : request_body_info.indexType, 
#                                'search_num' : request_body_info.searchNum}
#         vector_response = requests.post('http://localhost:51002/api/services/faiss/vector/search/imagenet', data=json.dumps(vector_request_data))
        
#         if vector_response.status_code != 200:
#             raise Exception(f"response error: {json.loads(vector_response.text)['error']}")
        
#         if json.loads(vector_response.text)["error"] != None:
#             raise Exception(f"vector error: {json.loads(vector_response.text)['error']}")
        
#         # remote
#         _directory_path, _file = os.path.split(img_path)
        
#         # remote 폴더 생성
#         sftp_client.remote_mkdir(os.path.join(rest_config.remote_folder, _temp_folder))
        
#         # remote 폴더에 이미지 저장
#         for i in os.listdir(_directory_path):
#             sftp_client.remote_copy_data(local_path=os.path.join(_directory_path, i), 
#                                          remote_path=os.path.join(rest_config.remote_folder, _temp_folder, i))        
#         shutil.rmtree(_directory_path)
#         return response.set_message()
    
#     except Exception as e:
#         LOG.error(traceback.format_exc())
#         return response.set_error(error=e)

# @router.post("/vectorImageSearch/vit/imageGenerate/imagen", summary="벡터 이미지 검색(clip-vit) - imagen", response_model=M.ResponseBase)
# async def vactor_vit(request: Request, request_body_info: M.VectorImageSearchVitReq):
#     """
#     ## 벡터 이미지 검색(clip-vit) - imagen
#     > imagen AI를 이용하여 이미지 생성 후 vector 검색 그후 결과 이미지 생성
    
#     ### options
#     > - modelType -> b32,b16,l14,l14_336
#     > - indexType -> l2,cos
    
#     """
#     response = M.ResponseBase()
#     try:  
#         if not download_range(request_body_info.searchNum, max=10):
#             raise Exception(f"downloadCound is invalid (current value = {request_body_info.searchNum})")
        
#         if request_body_info.modelType not in [M.VitModelType.b32, M.VitModelType.b16, M.VitModelType.l14, M.VitModelType.l14_336]:
#             raise Exception(f"modelType is invalid (current value = {request_body_info.modelType})")
        
#         if request_body_info.indexType not in [M.VitIndexType.cos, M.VitIndexType.l2]:
#             raise Exception(f"indexType is invalid (current value = {request_body_info.indexType})")
        
#         # query_image_path = imagen_generate_temp_image_path(image_prompt=request_body_info.prompt) #imagen
#         query_image_path = gemini_image(request_body_info.prompt) #gemini
        
#         vector_request_data = {'query_image_path' : query_image_path,
#                                'index_type' : request_body_info.indexType, 
#                                'model_type' : request_body_info.modelType,
#                                'search_num' : request_body_info.searchNum}

#         vector_response = requests.post('http://localhost:51002/api/services/faiss/vector/search/vit', data=json.dumps(vector_request_data))
        
#         vector_response_dict = json.loads(vector_response.text)
        
#         if vector_response.status_code != 200:
#             raise Exception(f"response error: {vector_response_dict['error']}")
        
#         if vector_response_dict["error"] != None:
#             raise Exception(f"vector error: {vector_response_dict['error']}")
        
#         result_image_paths = vector_response_dict.get('img_list').get('result_image_paths')
#         result_percents = vector_response_dict.get('img_list').get('result_percents')
        
#         if rest_config.config != 'release':
#             # 원격지 폴더 생성
#             remote_directory = os.path.join(rest_config.remote_folder, f"imagen_query_{request_body_info.modelType}_{request_body_info.indexType}_{request_body_info.prompt}_{D.date_file_name()}")
#             sftp_client.remote_mkdir(remote_directory)
            
#             # 원격지에 이미지 저장
#             sftp_client.remote_copy_data(local_path=query_image_path, remote_path=os.path.join(remote_directory,"query.png"))
            
#             for img_path, img_percent in zip(result_image_paths,result_percents):
#                 sftp_client.remote_copy_data(local_path=img_path, remote_path=os.path.join(remote_directory,f"search_{img_percent}.png"))
#         else:
#             local_directory = os.path.join(rest_config.local_folder, f"imagen_query_{request_body_info.modelType}_{request_body_info.indexType}_{request_body_info.prompt}_{D.date_file_name()}")
#             os.makedirs(local_directory, exist_ok=True)
            
#             shutil.copy(query_image_path, os.path.join(local_directory,"query.png"))
            
#             for img_path, img_percent in zip(result_image_paths,result_percents):
#                 shutil.copy(img_path, os.path.join(local_directory,f"search_{img_percent}.png"))
            

#         # Clean up temporary files
#         if 'query_image_path' in locals():
#             if os.path.exists(query_image_path):
#                 os.remove(query_image_path)
#                 del query_image_path
        
#         return response.set_message()
    
#     except Exception as e:
#         LOG.error(traceback.format_exc())
        
#         # Clean up temporary files
#         if 'query_image_path' in locals():
#             if os.path.exists(query_image_path):
#                 os.remove(query_image_path)
#                 del query_image_path
                
#         return response.set_error(error=e)
    
# @router.post("/vectorImageSearch/vit/imageGenerate/imagen/data", summary="벡터 이미지 검색(clip-vit) - imagen(data)", response_model=M.VectorImageSerachDataRes)
# async def vactor_vit_data(request: Request, request_body_info: M.VectorImageSearchVitDataReq):
#     """
#     ## 벡터 이미지 검색(clip-vit) - imagen
#     > imagen AI를 이용하여 이미지 생성 후 vector 검색 그후 결과 이미지데이터 return
    
#     ### options
#     > - modelType -> b32,b16,l14,l14_336
#     > - indexType -> l2,cos
    
#     """
#     response = M.VectorImageSerachDataRes()
#     query_image_data = ''
    
#     try: 
#         if not download_range(request_body_info.searchNum, max=10):
#             raise Exception(f"downloadCound is invalid (current value = {request_body_info.searchNum})")
        
#         if request_body_info.modelType not in [M.VitModelType.b32, M.VitModelType.b16, M.VitModelType.l14, M.VitModelType.l14_336]:
#             raise Exception(f"modelType is invalid (current value = {request_body_info.modelType})")
        
#         if request_body_info.indexType not in [M.VitIndexType.cos, M.VitIndexType.l2]:
#             raise Exception(f"indexType is invalid (current value = {request_body_info.indexType})")
        
#         # query_image_path = imagen_generate_temp_image_path(image_prompt=request_body_info.prompt) #imagen
#         query_image_path = gemini_image(request_body_info.prompt) #gemini
    
#         vector_request_data = {'query_image_path' : query_image_path,
#                                'index_type' : request_body_info.indexType, 
#                                'model_type' : request_body_info.modelType,
#                                'search_num' : request_body_info.searchNum}

#         vector_response = requests.post('http://localhost:51002/api/services/faiss/vector/search/vit', data=json.dumps(vector_request_data))
        
#         vector_response_dict = json.loads(vector_response.text)
        
#         if vector_response.status_code != 200:
#             raise Exception(f"response error: {vector_response_dict['error']}")
        
#         if vector_response_dict["error"] != None:
#             raise Exception(f"vector error: {vector_response_dict['error']}")
        
#         result_image_paths = vector_response_dict.get('img_list').get('result_image_paths')
#         result_percents = vector_response_dict.get('img_list').get('result_percents')
        
#         # 이미지 데이터 생성
#         vector_image_results = []
#         for img, percents in zip(result_image_paths, result_percents):
#             b64_data = image_to_base64_string(img)
#             float_percent = float(percents)
            
#             info = M.VectorImageResult(image=b64_data,percents=float_percent)
            
#             vector_image_results.append(info)

#         if request_body_info.querySend:
#             query_image_data = image_to_base64_string(query_image_path)
            
#         # Clean up temporary files
#         if 'query_image_path' in locals():
#             if os.path.exists(query_image_path):
#                 os.remove(query_image_path)
#                 del query_image_path
        
#         return response.set_message(vector_result=vector_image_results,query_img=query_image_data)
    
#     except Exception as e:
#         LOG.error(traceback.format_exc())
        
#         # Clean up temporary files
#         if 'query_image_path' in locals():
#             if os.path.exists(query_image_path):
#                 os.remove(query_image_path)
#                 del query_image_path
                
#         return response.set_error(error=e)

@router.post("/imageGenerator", summary="이미지 데이터 생성", response_model=M.ImageGenerateDataRes)
async def image_generator(request: Request, request_body_info: M.ImageGenerateReq):
    """
    ## 이미지 생성
    > 입력된 prompt로 이미지 생성 그후 결과 이미지데이터 return
    
    ### Input
    > 접두어(prefix)는 null값을 주어도 기본값 사용, 빈("")값 사용시 prefix는 사용안함
    > 최종 입력시 prefix, prompt 조합하여 내부적으로 최종 문장 완성
    
    ### Output
    > - 결과(imageData)는 base64로 변환된 데이터(image)
    
    ### Options
    > - prefix -> 접두어 (기본값: 하얀색 배경)
    > - prompt -> 프롬프트
    
    ### Notice
    > - 최종이미지에 배경이 없어야 이미지 검색시 유리하기때문에 꼭 prefix 옵션은 사용
    
    """
    
    response = M.ImageGenerateDataRes()
    try:
        if request_body_info.prefix == None:
            request_body_info.prefix = M.ImageGenerateReq.model_fields.get("prefix").default
        
        full_prompt = f"{request_body_info.prefix}, {request_body_info.prompt}" if request_body_info.prefix else f"{request_body_info.prompt}"
        
        temp_image_path = gemini_image(full_prompt) #TODO(jwkim) imagen3 으로 변경예정
        
        if os.path.exists(temp_image_path):
            image_data = image_to_base64_string(temp_image_path)
            
            # Clean up temporary files
            if 'temp_image_path' in locals():
                if os.path.exists(temp_image_path):
                    os.remove(temp_image_path)
                    del temp_image_path
            
            return response.set_message(image_data)
        else:
            raise Exception(f"image not generated(prefix: {request_body_info.prefix}, prompt:{request_body_info.prompt})")
        
    except Exception as e:
        LOG.error(traceback.format_exc())
        
        # Clean up temporary files
        if 'temp_image_path' in locals():
            if os.path.exists(temp_image_path):
                os.remove(temp_image_path)
                del temp_image_path
                
        return response.set_error(error=e)
        

@router.post("/vectorImageSearch/vit/inputImage/data", summary="벡터 이미지 검색(clip-vit) - input image(data)", response_model=M.VectorImageSerachDataRes)
async def vactor_vit_input_img_data(request: Request, request_body_info: M.VectorImageSearchVitInputImgReq):
    """
    ## 벡터 이미지 검색(clip-vit) - inputimage
    > 입력된 이미지로 vector 검색 그후 결과 이미지데이터 return
    
    ### Input
    > 입력이미지(inputImage)는 base64로 변환된 데이터 입력
    
    ### Output
    > - 결과(vectorResult)는 base64로 변환된 데이터(image), 유사도(percents)가 쌍으로 나오며, 요청한 searchNum 갯수에 맞춰서 결과가 나옴 
    > - queryImage는 Input시 입력한 inputImage 이미지 데이터
    
    ### Options
    > - modelType -> b32, b16, l14, l14_336 (기본값: l14)
    > - indexType -> l2, cos (기본값: l2)
    > - searchNum -> 결과이미지 갯수 (기본값: 4)
    
    ### Notice
    > - 일반검색시 indexType , modelType 은 기본값으로 사용
    > - indexType , modelType - 새로운 조합 (ex l14, cos)으로 처음 요청할경우 모델을 빌드하는 과정이 추가됨
    
    """
    response = M.VectorImageSerachDataRes()
    query_image_data = ''
    
    try: 
        if request_body_info.modelType not in [M.VitModelType.b32, M.VitModelType.b16, M.VitModelType.l14, M.VitModelType.l14_336]:
            raise Exception(f"modelType is invalid (current value = {request_body_info.modelType})")
        
        if request_body_info.indexType not in [M.VitIndexType.cos, M.VitIndexType.l2]:
            raise Exception(f"indexType is invalid (current value = {request_body_info.indexType})")
        
        query_image_path = os.path.join(TEMP_FOLDER, f'input_{D.date_file_name()}_query.png')
        os.makedirs(TEMP_FOLDER, exist_ok=True)
        save_base64_as_image_file(request_body_info.inputImage ,query_image_path)
               
        vector_request_data = {'query_image_path' : query_image_path,
                               'index_type' : request_body_info.indexType, 
                               'model_type' : request_body_info.modelType,
                               'search_num' : request_body_info.searchNum}

        vector_response = requests.post('http://localhost:51002/api/services/faiss/vector/search/vit', data=json.dumps(vector_request_data))
        
        vector_response_dict = json.loads(vector_response.text)
        
        if vector_response.status_code != 200:
            raise Exception(f"search server error: {vector_response_dict['error']}")
        
        if vector_response_dict["error"] != None:
            raise Exception(f"search result error: {vector_response_dict['error']}")
        
        result_image_paths = vector_response_dict.get('img_list').get('result_image_paths')
        result_percents = vector_response_dict.get('img_list').get('result_percents')
        
        # 이미지 데이터 생성
        vector_image_results = []
        for img, percents in zip(result_image_paths, result_percents):
            b64_data = image_to_base64_string(img)
            float_percent = float(percents)
            
            info = M.VectorImageResult(image=b64_data,percents=float_percent)
            
            vector_image_results.append(info)
            
        # Clean up temporary files
        if 'query_image_path' in locals():
            if os.path.exists(query_image_path):
                os.remove(query_image_path)
                del query_image_path
        
        return response.set_message(vector_result=vector_image_results,query_img=query_image_data)
    
    except Exception as e:
        LOG.error(traceback.format_exc())
        
        # Clean up temporary files
        if 'query_image_path' in locals():
            if os.path.exists(query_image_path):
                os.remove(query_image_path)
                del query_image_path
                
        return response.set_error(error=e)

 
# @router.post("/vectorImageSearch/vit/imageGenerate/imagen/report", summary="벡터 이미지 검색(clip-vit) - imagen, report 생성", response_model=M.ResponseBase)
# async def vactor_vit_report(request: Request, request_body_info: M.VectorImageSearchVitReportReq):
    """
    ## 벡터 이미지 검색(clip-vit) - imagen, report 생성
    > imagen AI를 이용하여 이미지 생성 후 vector 검색 그후 종합결과 이미지 생성
    
    ### Requriements
    > - googlecli 설치(https://cloud.google.com/sdk/docs/install?hl=ko#linux)
    
    ### options
    > - modelType -> b32,b16,l14,l14_336
    > - indexType -> l2,cos
    
    """
    response = M.ResponseBase()
    try:       
        if request_body_info.modelType not in [M.VitModelType.b32, M.VitModelType.b16, M.VitModelType.l14, M.VitModelType.l14_336]:
            raise Exception(f"modelType is invalid (current value = {request_body_info.modelType})")
        
        if request_body_info.indexType not in [M.VitIndexType.cos, M.VitIndexType.l2]:
            raise Exception(f"indexType is invalid (current value = {request_body_info.indexType})")
        
        # query_image_path = imagen_generate_temp_image_path(image_prompt=request_body_info.prompt) #imagen
        query_image_path = gemini_image(request_body_info.prompt) #gemini
        report_image_path = f"{os.path.splitext(query_image_path)[0]}_report.png"
        
        vactor_request_data = {'query_image_path' : query_image_path,
                               'index_type' : request_body_info.indexType, 
                               'model_type' : request_body_info.modelType,
                               'report_path' : report_image_path}

        vactor_response = requests.post('http://localhost:51002/api/services/faiss/vector/search/vit/report', data=json.dumps(vactor_request_data))
        
        if vactor_response.status_code != 200:
            raise Exception(f"response error: {json.loads(vactor_response.text)['error']}")
        
        if json.loads(vactor_response.text)["error"] != None:
            raise Exception(f"vector error: {json.loads(vactor_response.text)['error']}")
        
        if rest_config.config != 'release':
            # remote 폴더에 이미지 저장
            sftp_client.remote_copy_data(local_path=report_image_path, 
                                        remote_path=os.path.join(rest_config.remote_folder, f"imagen_report_vit_{request_body_info.prompt}_{D.date_file_name()}.png"))
        else:
            shutil.copy(report_image_path, os.path.join(rest_config.local_folder, f"imagen_report_vit_{request_body_info.prompt}_{D.date_file_name()}.png"))
         
        # Clean up temporary files
        if 'query_image_path' in locals():
            if os.path.exists(query_image_path):
                os.remove(query_image_path)
                del query_image_path
        if 'report_image_path' in locals():
            if os.path.exists(report_image_path):
                os.remove(report_image_path)
                del report_image_path
        
        return response.set_message()
    
    except Exception as e:
        LOG.error(traceback.format_exc())
        
        # Clean up temporary files
        if 'query_image_path' in locals():
            if os.path.exists(query_image_path):
                os.remove(query_image_path)
                del query_image_path
        if 'report_image_path' in locals():
            if os.path.exists(report_image_path):
                os.remove(report_image_path)
                del report_image_path
                
        return response.set_error(error=e)