package com.jasamedika.medifirst2000.interceptor;

import java.lang.reflect.Method;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang3.ArrayUtils;
import org.json.JSONArray;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import com.jasamedika.medifirst2000.constants.Constants;
import com.jasamedika.medifirst2000.dao.LoginUserDao;
import com.jasamedika.medifirst2000.dao.NotifikasiMessageObjekModulDao;
import com.jasamedika.medifirst2000.dao.RuanganDao;
import com.jasamedika.medifirst2000.entities.KelompokUser;
import com.jasamedika.medifirst2000.entities.LoginUser;
import com.jasamedika.medifirst2000.entities.MapObjekModulToKelompokUser;
import com.jasamedika.medifirst2000.entities.MapObjekModulToLoginUser;
import com.jasamedika.medifirst2000.entities.Pegawai;
import com.jasamedika.medifirst2000.entities.Ruangan;
import com.jasamedika.medifirst2000.notification.MessagePublisher;
import com.jasamedika.medifirst2000.notification.MessageSubscriber;
import com.jasamedika.medifirst2000.security.model.AppPermission;
import com.jasamedika.medifirst2000.security.service.TokenAuthenticationService;
import com.jasamedika.medifirst2000.service.MapObjekModulToKelompokUserService;
import com.jasamedika.medifirst2000.service.MapObjekModulToLoginUserService;
import com.jasamedika.medifirst2000.service.NotifMessagingSchedulerService;
import com.jasamedika.medifirst2000.service.NotifMessagingService;
import com.jasamedika.medifirst2000.service.NotifikasiMessageObjekModulService;
import com.jasamedika.medifirst2000.service.ObjekModulAplikasiService;
import com.jasamedika.medifirst2000.util.CommonUtil;
import com.jasamedika.medifirst2000.util.DateUtil;
import com.jasamedika.medifirst2000.vo.NotifMessagingSchedulerVO;
import com.jasamedika.medifirst2000.vo.NotifMessagingVO;
import com.jasamedika.medifirst2000.vo.NotifikasiMessageObjekModulVO;
import com.jasamedika.medifirst2000.vo.ObjekModulAplikasiVO;

/**
 * Interceptor class for All annotation method controller @AppPermission
 * 
 * @author Roberto
 * 
 *         direka ulang oleh Syamsu
 */

public class AppInterceptor implements HandlerInterceptor {
	
	private static final String[] PRINT_PATTERN = {"/lap_", "/lap-", "/lap", "/cetak_", "/cetak-", "/print_", "/print-" };

	private static final String[] ADD_PATTERN = {"/save_", "/save-", "/add_", "/add-", "/simpan_", "/simpan-"};
	
	private static final String[] UPDATE_PATTERN = {"/update_", "/update-", "/edit_", "/edit-", "/ubah_", "/ubah-"}; 

	private static final String[] DELETE_PATTERN = {"/delete_", "/delete-", "/hapus_", "/hapus-"}; 

	private final Logger LOG = LoggerFactory.getLogger(AppInterceptor.class);

	@Autowired
	private TokenAuthenticationService tokenAuthenticationService;

	@Autowired
	private LoginUserDao loginUserDao;

	@Autowired
	private MapObjekModulToKelompokUserService mapObjekModulToKelompokUserService;
	
	@Autowired
	private MapObjekModulToLoginUserService mapObjekModulToLoginUserService;

	@Autowired
	private ObjekModulAplikasiService<ObjekModulAplikasiVO> objekModulAplikasiService;
	
	@Autowired
	MessagePublisher<String, Object> messagePublisher;

	@Autowired
	MessageSubscriber messageSubscriber;
	
	@Autowired
	NotifMessagingService<NotifMessagingVO> notifMessagingService;
	
	@Autowired
	NotifikasiMessageObjekModulService<NotifikasiMessageObjekModulVO> notifikasiMessageObjekModulService;
	
	@Autowired
	NotifMessagingSchedulerService<NotifMessagingSchedulerVO> notifMessagingSchedulerService;

	@Autowired
	NotifikasiMessageObjekModulDao notifikasiModulMessageDao;
	
	@Autowired 
	RuanganDao ruanganDao;

	List<LoginUser> loginUser;

	String namaUser;
	
//	private int headerActionToAction(String action){
//		if ("save".equals(action)){
//			return AppPermission.ADD;
//		} else if ("edit".equals(action)){
//			return AppPermission.UPDATE;
//		} else if ("delete".equals(action)){
//			return AppPermission.DELETE;
//		} else if ("print".equals(action)){
//			return AppPermission.PRINT;
//		} else {
//			return AppPermission.VIEW;
//		}
//	}
	
	
	private boolean contains(String source, String[] matchers){
		
		
		if (CommonUtil.isNullOrEmpty(source) || ArrayUtils.isEmpty(matchers)){
			return false;
		}
		
		for (int i=0;i<matchers.length; i++){
			if (source.contains(matchers[i])){
				return true;
			}
		}
		
		return false;
	}
	
	private String filterUrlForm(String urlForm){
		
		String[] hasil = urlForm.split("/");
		System.out.println(hasil.length);
		StringBuilder potongan = new StringBuilder();
		for (int i=0; i<hasil.length && i<3; i++){
			potongan.append(hasil[i]).append("/");
		}
//		String current = urlForm;
//		int pos = 0;
//		int cpos = -1;
//		for (int i=0; i<4; i++){
//			pos = current.indexOf('/',pos+1);
//			if (pos > 0){
//				cpos = pos;
//			}else{
//				break;
//			}
//		}
//		String oye = urlForm.substring(0, cpos);
		return potongan.toString();
	}
	
	private boolean checkAuthSecure(HttpServletRequest request, HttpServletResponse response, String AlamatUrlForm, boolean supervisi) throws Exception {

		Authentication authentication = tokenAuthenticationService.getAuthentication(request);

		namaUser = authentication.getName();
		loginUser = loginUserDao.findByNamaUser(namaUser);

		if (CommonUtil.isNullOrEmpty(loginUser)) {
			LOG.info("Empty login user");
			response.setHeader("RequireSupervisor", "false");
			response.setHeader(Constants.MessageInfo.ERROR_MESSAGE, "Empty login user");
			response.setStatus(HttpServletResponse.SC_FORBIDDEN);
			return false;
		}
		return true;
	}
	
	private int checkUserPermision(LoginUser user, ObjekModulAplikasiVO objekModulAplikasiVO, int action){
		
		int result = -1;
		
		MapObjekModulToLoginUser modul = mapObjekModulToLoginUserService.findByObjekModulAplikasi(objekModulAplikasiVO.getId(), user.getId());		
		
		if (modul != null) {
			LOG.info("Module security match");
			result = 0;
			switch (action) {
				case AppPermission.ADD:
					if (modul.getSimpan()){
						result = 1;
					}	
					break;
				case AppPermission.UPDATE:
					if (modul.getEdit()){
						result = 1;
					}	
					break;
				case AppPermission.DELETE:
					if (modul.getHapus()){
						result = 1;
					}	
					break;
				case AppPermission.PRINT:
					if (modul.getCetak()){
						result = 1;
					}	
					break;
			}
		}
				
		return result;
	}
	
	private int checkKelompokUserPermision(LoginUser user, ObjekModulAplikasiVO objekModulAplikasiVO, int action){
		
		KelompokUser role = user.getKelompokUser();
		int result = -2;
		
		if (role != null) {
			MapObjekModulToKelompokUser modul = mapObjekModulToKelompokUserService.findByObjekModulAplikasi(objekModulAplikasiVO.getId(), role.getId());			
			result = -1;
			if (modul != null) {
				LOG.info("Module security match");
				result = 0;
				switch (action) {
					case AppPermission.ADD:
						if (modul.getSimpan()){
							result = 1;
						}	
						break;
					case AppPermission.UPDATE:
						if (modul.getEdit()){
							result = 1;
						}	
						break;
					case AppPermission.DELETE:
						if (modul.getHapus()){
							result = 1;
						}	
						break;
					case AppPermission.PRINT:
						if (modul.getCetak()){
							result = 1;
						}	
						break;
				}
			}
		}
				
		return result;
	}

	private boolean checkPermission(HttpServletRequest request, HttpServletResponse response, String AlamatUrlForm, int action) throws Exception {
		// Alter modified Syamsu
		List<ObjekModulAplikasiVO> objekModulAplikasi = objekModulAplikasiService.findByAlamatUrlForm(filterUrlForm(AlamatUrlForm));

		
		if (CommonUtil.isNullOrEmpty(objekModulAplikasi)){ 
			LOG.warn(AlamatUrlForm + " : Sementara defaultnya diloloskan semuanya di AppInterceptor jika tidak ada di dalam daftar objek modul aplikasi..");
			return true; // Defaultnya diloloskan semuanya...
		}
		
		if (!checkAuthSecure(request, response, AlamatUrlForm, false)) {
			return false;
		}
		
		int resultUser = checkUserPermision(loginUser.get(0), objekModulAplikasi.get(0), action);
		
		if (resultUser == 0){
			LOG.info("User {} has need superVisor for action in {} module application", namaUser, action);
			response.setHeader("RequireSupervisor", "true");
			response.setHeader(Constants.MessageInfo.ERROR_MESSAGE, "Action requires supervisor");
			response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
			return false;
		} else if (resultUser == 1){
			response.setHeader(Constants.MessageInfo.INFO_MESSAGE, "Supervise execution success");
			response.setStatus(HttpServletResponse.SC_OK);
			return true;
		} 
		
		int resultKelompokUser = checkKelompokUserPermision(loginUser.get(0), objekModulAplikasi.get(0), action);
		
		if (resultKelompokUser == -2){
			LOG.warn("Sementara defaultnya diloloskan semuanya di AppInterceptor jika tidak ada di dalam daftar kelompok user..");
			return true; // Defaultnya diloloskan semuanya...
//			LOG.info("User {} has no role to gain access restricted area", namaUser);
//			response.setHeader("RequireSupervisor", "false");
//			response.setHeader(Constants.MessageInfo.ERROR_MESSAGE,
//					"User " + namaUser + " has no role to gain access restricted area");
//			response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
//			return false;
		} else 	if (resultKelompokUser == -1){
			LOG.warn("Sementara defaultnya diloloskan semuanya di AppInterceptor jika tidak ada di dalam daftar Map objek modul to kelompok user..");
			return true; // Defaultnya diloloskan semuanya...
//			LOG.info("User {} has no access to module application", namaUser);
//			response.setHeader("RequireSupervisor", "false");
//			response.setHeader(Constants.MessageInfo.ERROR_MESSAGE,
//					"User " + namaUser + " has no access to module application");
//			response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
//			return false;
		} else if  (resultKelompokUser == 0) {
			LOG.info("User {} has need superVisor for action in {} module application", namaUser, action);
			response.setHeader("RequireSupervisor", "true");
			response.setHeader(Constants.MessageInfo.ERROR_MESSAGE, "Action requires supervisor");
			response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
			return false;
		} else {
			response.setHeader(Constants.MessageInfo.INFO_MESSAGE, "Supervise execution success");
			response.setStatus(HttpServletResponse.SC_OK);
			return true;
		}	 
	}

	/*
	 * return true untuk valid permission request ke controller method
	 */
	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
		////// Syamsu /////

		// TUTUP DULU PENGGUNAANNYA...

		HandlerMethod hm;
		Method method = null;
//		int methodApp = AppPermission.VIEW;

		response.setHeader("Access-Control-Expose-Headers", "RequireSupervisor" + ","
				+ Constants.MessageInfo.ERROR_MESSAGE + "," + Constants.MessageInfo.INFO_MESSAGE);

		////// Syamsu /////

		String AlamatUrlForm = request.getHeader(Constants.HttpHeader.URL_FORM) == null ? "": request.getHeader(Constants.HttpHeader.URL_FORM);
		
		// Buat Om, Kang, Aa Reza terkait Security Role
		//String KdRuangan = null;
		String KdRuangan = request.getHeader(Constants.HttpHeader.KD_RUANGAN) == null ? "": request.getHeader(Constants.HttpHeader.KD_RUANGAN);

		int action = AppPermission.VIEW;
				
		if (CommonUtil.isNullOrEmpty(AlamatUrlForm)){
			//LOG.warn("Sementara defaultnya di loloskan semuanya di AppInterceptor jika tidak ada header 'AlamatUrlForm' ..");
			return true; // Lewatin dulu sementara;
		}
		
		if (CommonUtil.isNullOrEmpty(KdRuangan) || "0".equals(KdRuangan)){
			LOG.warn("Sementara defaultnya diloloskan semuanya di AppInterceptor jika tidak ada header 'KdRuangan' atau header 'KdRuangan'nya 0 ..");
			return true; // Lewatin dulu sementara;
		}

		//String headerAction = request.getHeader(Constants.HttpHeader.ACTION) == null ? "" : request.getHeader(Constants.HttpHeader.ACTION);

		String URI = request.getRequestURI();
		String methodHttp = request.getMethod();

		try {
			// Alter modified Syamsu
			if (handler instanceof org.springframework.web.method.HandlerMethod) {
				hm = (HandlerMethod) handler;
				method = hm.getMethod();
			} else {
				return checkAuthSecure(request, response, AlamatUrlForm, true);
			}

			// AlamatUrlForm // Alter modified Syamsu
			boolean usingAnno = method != null && method.isAnnotationPresent(AppPermission.class);
			
			boolean postM = "POST".equals(methodHttp);
			boolean signInOut = !URI.contains("auth/sign-in") && !URI.contains("auth/sign-out");
			boolean getM = "GET".equals(methodHttp);
			boolean cetak = contains (URI, PRINT_PATTERN);
			
			/*(URI.contains("/lap_") || URI.contains("/lap-") || URI.contains("/lap")
					|| URI.contains("/cetak_") || URI.contains("/print_") || URI.contains("/cetak-")
					|| URI.contains("/print-"));*/

			boolean simpan = contains (URI, ADD_PATTERN);
			
			/*(URI.contains("/save_") || URI.contains("/add_") || URI.contains("/simpan_")
					|| URI.contains("/save-") || URI.contains("/add-") || URI.contains("/simpan-"));*/

			boolean ubah = contains (URI, UPDATE_PATTERN);
			
			/*(URI.contains("/update_") || URI.contains("/edit_") || URI.contains("/ubah_")
					|| URI.contains("/update-") || URI.contains("/edit-") || URI.contains("/ubah-"));*/

			boolean hapus =  contains (URI, DELETE_PATTERN); 
			
			/*(URI.contains("/delete_") || URI.contains("/hapus_") || URI.contains("/delete-")
					|| URI.contains("/hapus-")); */

			if (usingAnno) {
				if (method.getAnnotation(AppPermission.class) != null) {
					action = method.getAnnotation(AppPermission.class).value();
				}

				if (AppPermission.SPECIALS == action /* && "#/home".equals(AlamatUrlForm) */) {
					return true;
				}
			}

			if (getM && cetak) {

				action = AppPermission.PRINT;

//				if (headerAction != null && !"".equals(headerAction)) {
//					action = headerActionToAction(headerAction);
//				}

				if (method.getAnnotation(AppPermission.class) != null) {
					action = method.getAnnotation(AppPermission.class).value();
				}

				return checkPermission(request, response, AlamatUrlForm, action);
			}

			if ((usingAnno || postM) && signInOut) {

				if (simpan) {
					action = AppPermission.ADD;
				} else if (ubah) {
					action = AppPermission.UPDATE;
				} else if (hapus) {
					action = AppPermission.DELETE;
				} else if (cetak) {
					action = AppPermission.PRINT;
				}

//				if (headerAction != null && !"".equals(headerAction)) {
//					action = headerActionToAction(headerAction);
//				}
				
				if (method.getAnnotation(AppPermission.class) != null) {
					action = method.getAnnotation(AppPermission.class).value();
				}

				return checkPermission(request, response, AlamatUrlForm, action);

			}

		} catch (Exception e) {
			e.printStackTrace();
			System.out.println("Not Found " + request.getRequestURL());

			LOG.info("Error accured unauthorized");
			response.setHeader(Constants.MessageInfo.ERROR_MESSAGE, "Something wrong happened");
			response.setHeader("RequireSupervisor", "false");
			response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
			return false;
		}

		// TUTUP DULU PENGGUNAANNYA...

		return true;
	}
	

	@Override
	public void postHandle(HttpServletRequest request, HttpServletResponse response, Object obj, ModelAndView mav) throws Exception {}
	
	
	@Override
	public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object obj, Exception ex) throws Exception {
		
		String AlamatUrlForm = request.getHeader(Constants.HttpHeader.URL_FORM) == null ? ""
				: request.getHeader(Constants.HttpHeader.URL_FORM);
		String KdRuangan = request.getHeader(Constants.HttpHeader.KD_RUANGAN) == null ? ""
				: request.getHeader(Constants.HttpHeader.KD_RUANGAN);
		
		String idRuanganTujuan = request.getHeader(Constants.HttpHeader.KD_RUANGAN_T) == null ? ""
				: request.getHeader(Constants.HttpHeader.KD_RUANGAN_T);
		
		String idRuanganTujuanA = request.getHeader(Constants.HttpHeader.KD_RUANGAN_A) == null ? ""
				: request.getHeader(Constants.HttpHeader.KD_RUANGAN_A);
		
		String tglKirim = request.getHeader(Constants.HttpHeader.TGL_KIRIM) == null ? ""
				: request.getHeader(Constants.HttpHeader.TGL_KIRIM);
		
		boolean notHttpOK = response.getStatus() >= HttpServletResponse.SC_BAD_REQUEST;
		boolean notLewatMenu = CommonUtil.isNullOrEmpty(AlamatUrlForm) || CommonUtil.isNullOrEmpty(KdRuangan);
		
		Integer ruanganAsalId = 0;
				
		try {
			ruanganAsalId = Integer.parseInt(KdRuangan);			
		}catch(Exception e){
			ex = e;
		}
		
		
		boolean adaError = CommonUtil.isNotNullOrEmpty(ex);
		if (notHttpOK || notLewatMenu || adaError){
			return;
		}

		Authentication authentication = tokenAuthenticationService.getAuthentication(request);
		
		if (CommonUtil.isNullOrEmpty(authentication)){
			return;
		}
		
		namaUser = authentication.getName();
		loginUser = loginUserDao.findByNamaUser(namaUser);
		
		if (CommonUtil.isNullOrEmpty(loginUser)) {
			return;
		}	
						
		String potongan = filterUrlForm(AlamatUrlForm);
		List<ObjekModulAplikasiVO> objekModulAplikasiVOs = objekModulAplikasiService.findByAlamatUrlForm(potongan);

		if (CommonUtil.isNullOrEmpty(objekModulAplikasiVOs)){ 
			return;
		}
		
		String URI = request.getRequestURI();
		
		Integer objekModulAplikasId = objekModulAplikasiVOs.get(0).getId();
		
		List<NotifMessagingVO> notifMessagingVOs = notifMessagingService.findByObjekModulAplikasiIdAndUrlBackEndOrUrlBackEndIsNull(objekModulAplikasId, URI);
		
		if (CommonUtil.isNullOrEmpty(notifMessagingVOs)) {
			return;
		}
		
		Integer notifMessagingId = notifMessagingVOs.get(0).getId();
		
		if (CommonUtil.isNullOrEmpty(tglKirim)) {
			
			
			List<Integer> ruanganTujuansId = new ArrayList<>();
			System.out.println("--");
			
			if (!"".equals(idRuanganTujuan)){
				JSONArray ruanganTujuanIds = new JSONArray(idRuanganTujuan);
				for (int i=0; i<ruanganTujuanIds.length(); i++){
					Integer ruanganTujuanId = ruanganTujuanIds.optInt(i, 0);
					ruanganTujuansId.add(ruanganTujuanId);
				}	
			}
			
			if (!"".equals(idRuanganTujuanA) && ruanganTujuansId.isEmpty()) {
				JSONArray ruanganTujuanIds = new JSONArray(idRuanganTujuanA);
				for (int i=0; i<ruanganTujuanIds.length(); i++){
					Integer ruanganTujuanId = ruanganTujuanIds.optInt(i, 0);
					ruanganTujuansId.add(ruanganTujuanId);
				}
			}
			
			MessagePublisher.RabbitHole rabbitHole = messagePublisher.getRabbitHole();
			
			Pegawai pegawai = loginUser.get(0).getPegawai();
			Ruangan ruanganAsal = ruanganDao.findById(ruanganAsalId);
			
								
			if (ruanganTujuansId.size() > 0){
				try{
					rabbitHole.sendNotif(rabbitHole, ruanganAsal, pegawai, notifikasiMessageObjekModulService, notifMessagingId, ruanganTujuansId);
				}catch(Exception e){
					e.printStackTrace();
					LOG.info(DateUtil.now()+" send notif dari Ruangan {} dengan ruanganId {} pada notifMessageId {} ada masalah {}", 
							ruanganAsal.getNamaRuangan(), ruanganAsalId, notifMessagingId, e.getMessage());
				}
			}
			
		} else {
			JSONArray tglKirims = new JSONArray(tglKirim);
			JSONArray ruanganTujuanIds = new JSONArray(idRuanganTujuan);
			SimpleDateFormat myFormat = new SimpleDateFormat("yyyy-MM-dd");
			
			for (int i=0; i<tglKirims.length(); i++){
				String ctglKirim = tglKirims.optString(i, "");
				Integer cRuanganTujuanId = ruanganTujuanIds.optInt(i,0);
				Date date = myFormat.parse(ctglKirim);
				
				NotifMessagingSchedulerVO vo = new NotifMessagingSchedulerVO();
				
				vo.setTglKirim(date);
				vo.setTerkirim(false);
				vo.setNotifMessagingId(notifMessagingId);
				vo.setRuanganIdAsal(ruanganAsalId);
				vo.setRuanganIdTujuan(cRuanganTujuanId);
				vo.setPegawaiId(loginUser.get(0).getPegawai().getId());
				
				vo.setKdProfile((short)0);
				vo.setKodeExternal("");
				vo.setNamaExternal("");
				vo.setReportDisplay("");
				vo.setStatusEnabled(true);

				notifMessagingSchedulerService.add(vo);
			}
		}
	}
	
	
//	<T extends BaseMasterVO> T convertToVO(T t, Object o){
//		BeanUtils.copyProperties(t, o);
//		return t;
//	}
	
	// try{
	//
	//
	// String AlamatUrlForm =
	// request.getHeader(Constants.HttpHeader.URL_FORM) == null ? "" :
	// request.getHeader(Constants.HttpHeader.URL_FORM);
	// String KdRuangan = request.getHeader(Constants.HttpHeader.KD_RUANGAN)
	// == null ? "" : request.getHeader(Constants.HttpHeader.KD_RUANGAN);
	//
	// Authentication authentication =
	// tokenAuthenticationService.getAuthentication(request);
	//
	// namaUser = authentication.getName();
	// loginUser = loginUserDao.findByNamaUser(namaUser);
	//
	//
	// if (loginUser.isEmpty()) {
	// publisher.BroadcastMessage(KdRuangan, namaUser, AlamatUrlForm);
	// }
	//
	//
	//
	//
	//// String routingKeyAndQueueName = "ruanganId." + KdRuangan;
	////
	//// publisher.sendRabbitMQNotification("127.0.0.1", "ruanganId." +
	// KdRuangan, "Kd Ruangan : " + KdRuangan + ", AlamatUrlForm : " +
	// AlamatUrlForm);
	////
	//// subscriber.startRabbitMQNotification("127.0.0.1",
	// routingKeyAndQueueName);
	//// subscriber.listenRabbitMQNotification(routingKeyAndQueueName,
	// subscriber.getDefaultConsumer(), false);
	//// subscriber.stopRabbitMQNotification();
	//
	// }catch(Exception e){
	// //e.printStackTrace();
	// }

	
	
//	//String urlSocket = messagePublisher.GetSettingDataFixed("UrlRabbitMQMessaging"); sementara kunci dulu.
//	
//	String urlSocket = "127.0.0.1";
//	
//	List<NotifikasiMessageObjekModulVO> notifikasiMessageObjekModulVOs = notifikasiMessageObjekModulService.findByNotifMessagingIdAndRuanganId(notifMessagingId, ruanganTujuansId);
//	
//	if (CommonUtil.isNullOrEmpty(notifikasiMessageObjekModulVOs)) {
//		return;
//	}
//	
//	Integer ruanganIdtemp = 0;
//	boolean connect = false;
//	
//	for (NotifikasiMessageObjekModulVO vo : notifikasiMessageObjekModulVOs){
//		Ruangan ruangan = vo.getRuangan();
//		ModulAplikasi modulAplikasi = vo.getModulAplikasi();
//		ObjekModulAplikasi objekModulAplikasi = vo.getObjekModulAplikasi();
//		String customURLObjekModul = vo.getCustomURLObjekModul();
//		String titleNotifikasi = vo.getTitleNotifikasi();
//		String pesanNotifikasi = vo.getPesanNotifikasi();
//		String namaFungsiFrontEnd = vo.getNamaFungsiFrontEnd();
//		
//		if (ruangan.getId() ==  ruanganId){
//			continue;
//		}
//		
//		RuanganVO dariRuangan = ruanganService.findById(ruanganId);
//		
//		if (ruanganIdtemp != ruangan.getId()){		
//			if (connect){
//				rabbitHole.close();
//			}
//			rabbitHole.connect(urlSocket, String.valueOf(ruangan.getId()));
//			connect = true;
//			ruanganIdtemp = ruangan.getId();
//		}
//		
//		Map<String, Object> map = new HashMap<>();
//		map.put("title", titleNotifikasi);
//		map.put("dariRuangan", dariRuangan);
//		map.put("ruanganId", ruangan.getId());
//		map.put("ruangan", convertToVO(new RuanganVO(), ruangan));
//		map.put("modulAplikasi", convertToVO(new ModulAplikasiVO(), modulAplikasi));
//		map.put("objekModulAplikasi", convertToVO(new ObjekModulAplikasiVO(), objekModulAplikasi));
//		map.put("titleNotifikasi", titleNotifikasi);
//		map.put("pesanNotifikasi", pesanNotifikasi);
//		map.put("namaFungsiFrontEnd", namaFungsiFrontEnd);
//		map.put("fromPegawai", loginUser.get(0).getPegawai());
//		map.put("urlForm",CommonUtil.isNullOrEmpty(customURLObjekModul)? objekModulAplikasi.getAlamatUrlForm() : customURLObjekModul);
//							
//		rabbitHole.sendRabbitMQNotification(gson.toJson(map));
//
//		//messagePublisher.BroadcastMessage(map);
//	}
//	if (connect){
//		rabbitHole.close();
//	}	
	
	
//	private static final  TypeAdapterFactory FACTORY = new TypeAdapterFactory() {
//	    @Override
//	    @SuppressWarnings("unchecked")
//	    public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> type) {
//	        return (HibernateProxy.class.isAssignableFrom(type.getRawType())
//	                ? (TypeAdapter<T>) new HibernateProxyTypeAdapter((TypeAdapter)gson.getAdapter(TypeToken.get(type.getRawType().getSuperclass()))) 
//	     : null);
//	    }
//	};
//
//	
//	private static final class HibernateProxyTypeAdapter extends TypeAdapter<HibernateProxy> {
//
//		private final TypeAdapter<Object> delegate;
//
//		private HibernateProxyTypeAdapter(TypeAdapter<Object> delegate) {
//		    this.delegate = delegate;
//		}
//
//	    @Override
//	    public HibernateProxy read(JsonReader r) throws IOException {
//	        throw new UnsupportedOperationException("Not supported");
//	    }
//
//	    @SuppressWarnings({"rawtypes", "unchecked"})
//	    @Override
//	    public void write(JsonWriter out, HibernateProxy value) throws IOException {
//	        if (value == null) {
//	            out.nullValue();
//	            return;
//	        }
//	        
//	        
//	        
//	        delegate.write(out, ((HibernateProxy) value).getHibernateLazyInitializer().getImplementation());
//	    }		
//	}
}



/*
 * else if (method.isAnnotationPresent(AppMenuPermision.class)){
 * 
 * Authentication authentication =
 * tokenAuthenticationService.getAuthentication(request);
 * 
 * String namaUser = authentication.getName();
 * 
 * List<LoginUser> loginUser =
 * loginUserDao.findByNamaUser(namaUser);
 * 
 * if (loginUser.isEmpty()) { // untuk testing false
 * response.addHeader("Access-Control-Expose-Headers",
 * "content-type");
 * response.setHeader(Constants.MessageInfo.ERROR_MESSAGE, "User " +
 * namaUser + " can not access current menu ");
 * response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); return
 * false; }
 * 
 * // get user login if (!loginUser.isEmpty()) { LoginUser user =
 * loginUser.get(0); }else{ LOG.info("User {} is unauthorized",
 * namaUser);
 * response.setHeader(Constants.MessageInfo.ERROR_MESSAGE,
 * "User is unauthorized");
 * response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); return
 * false; } }
 */