package com.eactive.eai.rms.ext.kakaocard.cm;

import java.io.File;
import java.io.IOException;
import java.nio.file.DirectoryStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Properties;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;

import com.eactive.eai.common.util.DatetimeUtil;
import com.eactive.eai.rms.bap.loader.service.TransactionBAPServiceImpl;
import com.eactive.eai.rms.common.cm.CmLogService;
import com.eactive.eai.rms.common.context.MonitoringContext;
import com.eactive.eai.rms.common.datasource.DataSourceType;
import com.eactive.eai.rms.common.datasource.DataSourceTypeManager;
import com.eactive.eai.rms.ext.kakaocard.cm.except.CmInsertException;
import com.eactive.eai.rms.onl.common.util.FileWriteUtil;

@Service("kakaoCardCmFepBatchService")
public class KakaoCardCmBapService extends KakaoCardCmAbstractService {
   
   @Autowired @Qualifier("monitoringContext")
    private MonitoringContext monitoringContext;
   
   @Autowired @Qualifier("loaderBAPService")
   private TransactionBAPServiceImpl loaderService;
   
   @Override
   public boolean supportsType(String serviceType) {
      return DataSourceTypeManager.BAP.equals(serviceType);
   }

   @Override
   public void startDeploy(String serviceType, String commitId) throws Exception {
      final String deployId = commitId;
      final String rollbackYn = "N"; // FIXME
      final String deployStartTime = DatetimeUtil.getCurrentDateTime();
      
      Properties prop = monitoringContext.getProperties();
      String uploadPath   = prop.getProperty(MonitoringContext.CM_DEVELOPER_UPLOAD_PATH,    CM_DEVELOPER_UPLOAD_PATH_DEFAULT);
      
      try {
         
         storeResourceFilesFromAWS_S3(serviceType, commitId);
         
         List<String> appCodes = getAppCodesFromDirectory(serviceType, commitId);
         
         this.transactionDeployResources(serviceType, commitId, appCodes);
         
         try {
            cmLogging(uploadPath, serviceType, "ALL", deployId, CmLogService.DEPOLY_SUCCESS, rollbackYn, "", deployStartTime, DatetimeUtil.getCurrentDateTime());
         } catch (Exception log_e) {
            logger.error("CM작업이 정상적으로 종료되었으나, 로깅 중 에러가 발생하였습니다. 해당 에러는 throw되지 않습니다.", log_e);
         }
         
      } catch (Exception e) {
         
         /** Error Log **/
         try {
            cmLogging(uploadPath, serviceType, "ALL", deployId, CmLogService.DEPOLY_FAIL, rollbackYn, e.getMessage(), deployStartTime, DatetimeUtil.getCurrentDateTime());
         } catch (Exception log_e) {
            logger.error("CM작업의 실패로깅 중 에러가 발생하였습니다. 해당 에러는 throw되지 않습니다.", log_e);
         }
         
         throw e;
      }
      
   }

   @Override
   public void transactionDeployResources(String serviceType, String commitId, List<String> appCodes)
         throws Exception {
      final DataSourceType dt = DataSourceTypeManager.getDataSourceType(serviceType);
      
      Properties prop = monitoringContext.getProperties();
      final String uploadPath   = prop.getProperty(MonitoringContext.CM_DEVELOPER_UPLOAD_PATH,    CM_DEVELOPER_UPLOAD_PATH_DEFAULT);
      
      try {
         
         for (String appCode : appCodes) {
            
            String path_uploaded_servicetype_commitId_app_interface = 
                  uploadPath + 
                  serviceType + File.separator + 
                  commitId + File.separator + 
                  appCode + File.separator + 
                  FileWriteUtil.BAP_CM_DIR + File.separator;

            try (DirectoryStream<Path> stream = Files.newDirectoryStream(Paths.get(path_uploaded_servicetype_commitId_app_interface))) {
               for (Path item : stream) {
                  if (Files.isRegularFile(item)) {
                     loaderService.insertFileInfoLoading(dt, path_uploaded_servicetype_commitId_app_interface, item.getFileName().toString());
                  }
               }
            } catch (IOException e) {
               throw e;
            }

         }
         
      } catch (Exception e) {
         logger.error("Metadata Deploy INSERT ERROR. ", e);
         throw new CmInsertException(e);
      }
      
   }

   @Override
   public void promote(String serviceType, String commitId) {
      // TODO Auto-generated method stub
      
   }

   @Override
   public void rollback(String serviceType, String commitId) {
      // TODO Auto-generated method stub
      
   }
   
}