package jp.agentec.abook.abv.bl.websocket;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import jp.agentec.abook.abv.bl.common.ABVEnvironment;
import jp.agentec.abook.abv.bl.common.log.LogLevel;
import jp.agentec.abook.abv.bl.common.nw.PCNetworkAdapter;
import jp.agentec.abook.abv.bl.dto.MeetingDto;

import org.json.adf.JSONObject;
import org.junit.Test;

public class MeetingManagerTest {
	private volatile boolean presenterWait = true;
	private volatile boolean subscriberWait = true;
	private List<MeetingManager> meetingManagerList = new ArrayList<MeetingManager>();
	
	int meetingId = -1;
//	int meetingId = 1151; // 実機で司会者テストする場合、testPublish=falseにして、実機でmeetingIdを確認してセットして実行する。
	int interval = 1000;
//	int interval = 5000; // 司会者が送るコマンドの間隔ミリ秒
	private int clientCount = 500; // 参加者の数（参加者を実機のみでする場合は0をセット）
	private boolean testPublish = true; // 司会者を実行する場合
	
	public MeetingManagerTest() throws IOException {
	}

	@Test
	public void test() throws Exception {
		ABVEnvironment env = ABVEnvironment.getInstance();
		env.websocketServerHttpUrl = "https://192.168.11.123/v1";
		env.websocketServerWsUrl = "wss://192.168.11.123/v1";
		env.networkAdapter = new PCNetworkAdapter();
		env.setLogLevel(LogLevel.verbose);
		
		int count = 0;
		try {
			Thread t = new Thread(){
				public void run() {
					try {
						publish();
					} catch (Exception e) {
						log(e);
					}
				}
			};
			if (testPublish) {
				t.start();
				while (subscriberWait) {
					Thread.sleep(1000);
				}
			}
			
			
			for (int i = 0; i < clientCount ; i++) {
				try {
					subscribe();
					count++;
				} catch (Exception e) {
					e.printStackTrace();
					try {
						subscribe();
						count++;
					} catch (Exception e2) {
						e2.printStackTrace();
					}
				}
			}
			presenterWait = false;
			
			if (testPublish) {
				t.join();
			}
			
			for (MeetingManager meetingManager : meetingManagerList) {
				meetingManager.joinWebSocketClientThread();
			}

		} catch (Exception e) {
			log(e);
		}
		log("---- result ----");
		log("Thread count=" + count);
		for (String s : DefaultWebSocketClient.log) {
			log(s);
		}
	}

	private void log(String msg) {
		System.out.println(msg);
	}

	private void log(Exception e) {
		log(e.toString());
		for (StackTraceElement stackTraceElement :  e.getStackTrace()) {
			log(stackTraceElement.toString());
		}
	}

	public void publish() throws Exception {
		MeetingManager meetingManager = MeetingManager.getInstance();
		String skey = meetingManager.getSessionKey("83da5f2d19e27c1b75115151000fab20", "ts", false);
		log("skey = " + skey);
		List<MeetingDto> list = meetingManager.getMeetingList(skey);
		for (MeetingDto meetingDto : list) {
			log(meetingDto.toString());
			if (meetingDto.ownerLoginId.equals("asdf")) {
				meetingManager.deleteMeeting(meetingDto.meetingId, skey);
			}
		}
		
		try {
		meetingId = meetingManager.createMeeting(skey, "あいうえお2", null);
//		meetingId = webSocketManager.createMeeting(skey, "あいうえお222", null);
		log("meetingId = " + meetingId);
		
		list = meetingManager.getMeetingList(skey);
		for (MeetingDto meetingDto : list) {
			log(meetingDto.toString());
			if (meetingId == -1 && meetingDto.ownerLoginId.equals("test")) {
				meetingId = meetingDto.meetingId;
			}
		}
		
//		webSocketManager.join(meetingId, skey, "hogeboke", true);
		meetingManager.join(meetingId, skey, null, true);
		subscriberWait  = false;
		
//		Thread.sleep(5000); // ★この間に端末で入室すること
		while (presenterWait ) {
			Thread.sleep(1000);
		}
		
		long contentId = 1176L;
		int pageNumber = 1; // 内部状態のページ（Node.jsに送るページは１加算）
		JSONObject json = null;

		// ts事業者、コンテンツ「医療～コピー」を使用
    	meetingManager.sendWs(MeetingManager.CMD_OPEN, contentId, 0, null, null);
		Thread.sleep(interval);

    	meetingManager.sendWs(MeetingManager.CMD_MOVEPAGE, contentId, 4, null, null);
		Thread.sleep(interval);
    	meetingManager.sendWs(MeetingManager.CMD_MOVEPAGE, contentId, 3, null, null);
		Thread.sleep(interval);
    	meetingManager.sendWs(MeetingManager.CMD_MOVEPAGE, contentId, pageNumber, null, null);
		Thread.sleep(interval);

    	meetingManager.sendWs(MeetingManager.CMD_ACTION, contentId, pageNumber, 97L, null); // URL専用
		Thread.sleep(interval);
    	meetingManager.sendWs(MeetingManager.CMD_CLOSEPOPUP, contentId, pageNumber, 97L, null); 
		Thread.sleep(interval);

//    	meetingManager.sendWs(MeetingManager.CMD_ACTION, contentId, pageNumber, 98L, null); // URLデフォルト
//		Thread.sleep(interval);
//    	meetingManager.sendWs(MeetingManager.CMD_CLOSEPOPUP, contentId, pageNumber, 98L, null); 
//		Thread.sleep(interval);

    	meetingManager.sendWs(MeetingManager.CMD_ACTION, contentId, pageNumber, 99L, null); // ページジャンプ
		Thread.sleep(interval);
    	meetingManager.sendWs(MeetingManager.CMD_MOVEPAGE, contentId, pageNumber, null, null);
		Thread.sleep(interval);

    	meetingManager.sendWs(MeetingManager.CMD_ACTION, contentId, pageNumber, 100L, null); // イメージプレビュー
		Thread.sleep(interval);
		json = new JSONObject();
		json.put(MeetingManager.IMAGE_INDEX, 1);
    	meetingManager.sendWs(MeetingManager.CMD_IMAGEPREVIEWACTION, contentId, pageNumber, 100L, json);
		Thread.sleep(interval);
		json.put(MeetingManager.IMAGE_INDEX, 2);
    	meetingManager.sendWs(MeetingManager.CMD_IMAGEPREVIEWACTION, contentId, pageNumber, 100L, json);
		Thread.sleep(interval);
		json.put(MeetingManager.IMAGE_INDEX, 0);
    	meetingManager.sendWs(MeetingManager.CMD_IMAGEPREVIEWACTION, contentId, pageNumber, 100L, json);
		Thread.sleep(interval);
    	meetingManager.sendWs(MeetingManager.CMD_CLOSEPOPUP, contentId, pageNumber, 100L, null); 
		Thread.sleep(interval);

//    	meetingManager.sendWs(MeetingManager.CMD_ACTION, contentId, pageNumber, 101L, null); // Email
//		Thread.sleep(5000); // ★手動で戻すこと

    	meetingManager.sendWs(MeetingManager.CMD_ACTION, contentId, pageNumber, 103L, null); // 音楽
		Thread.sleep(interval);
		
    	meetingManager.sendWs(MeetingManager.CMD_ACTION, contentId, pageNumber, 102L, null); // 全画面Video
		Thread.sleep(interval);
		json = new JSONObject();
		json.put(MeetingManager.PLAY_TIME, 6);
    	meetingManager.sendWs(MeetingManager.CMD_MOVIEACTION, contentId, pageNumber, 102L, json);
		Thread.sleep(interval);

		json = new JSONObject();
		json.put(MeetingManager.TYPE, MeetingManager.PAUSE);
    	meetingManager.sendWs(MeetingManager.CMD_MOVIEACTION, contentId, pageNumber, 102L, json);
		Thread.sleep(interval);
		
		json.put(MeetingManager.TYPE, MeetingManager.START);
    	meetingManager.sendWs(MeetingManager.CMD_MOVIEACTION, contentId, pageNumber, 102L, json);
		Thread.sleep(interval);
    	meetingManager.sendWs(MeetingManager.CMD_CLOSEPOPUP, contentId, pageNumber, 102L, null); 
		Thread.sleep(interval);
		
    	meetingManager.sendWs(MeetingManager.CMD_ACTION, contentId, pageNumber, 104L, null); // Popup
		Thread.sleep(interval);
    	meetingManager.sendWs(MeetingManager.CMD_CLOSEPOPUP, contentId, pageNumber, 104L, null); 
		Thread.sleep(interval);
		
    	meetingManager.sendWs(MeetingManager.CMD_ACTION, contentId, pageNumber, 106L, null); // HTML
		Thread.sleep(interval);
    	meetingManager.sendWs(MeetingManager.CMD_CLOSEPOPUP, contentId, pageNumber, 106L, null); 
		Thread.sleep(interval);

    	meetingManager.sendWs(MeetingManager.CMD_ACTION, contentId, pageNumber, 58L, null); // アンケート・全画面
		Thread.sleep(interval);
		json = new JSONObject();
		json.put(MeetingManager.IS_BIG_FONT_SIZE, false);
    	meetingManager.sendWs(MeetingManager.CMD_QUESTIONNAIREACTION, contentId, pageNumber, 58L, json);
		Thread.sleep(interval);
		json.put(MeetingManager.IS_BIG_FONT_SIZE, true);
    	meetingManager.sendWs(MeetingManager.CMD_QUESTIONNAIREACTION, contentId, pageNumber, 58L, json);
		Thread.sleep(interval);
		
		json = new JSONObject();
		json.put(MeetingManager.ALPHA, 0.3f);
    	meetingManager.sendWs(MeetingManager.CMD_QUESTIONNAIREACTION, contentId, pageNumber, 58L, json);
		Thread.sleep(interval);
		
    	meetingManager.sendWs(MeetingManager.CMD_CLOSEPOPUP, contentId, pageNumber, 58L, null); 
		Thread.sleep(interval);
		
    	meetingManager.sendWs(MeetingManager.CMD_ACTION, contentId, pageNumber, 59L, null); // アンケート・半画面
		Thread.sleep(interval);
		json = new JSONObject();
		json.put(MeetingManager.IS_RIGHT, false);
    	meetingManager.sendWs(MeetingManager.CMD_QUESTIONNAIREACTION, contentId, pageNumber, 59L, json);
		Thread.sleep(interval);
		json.put(MeetingManager.IS_RIGHT, true);
    	meetingManager.sendWs(MeetingManager.CMD_QUESTIONNAIREACTION, contentId, pageNumber, 59L, json);
		Thread.sleep(interval);
		
		json = new JSONObject();
		json.put(MeetingManager.IS_BIG_FONT_SIZE, false);
    	meetingManager.sendWs(MeetingManager.CMD_QUESTIONNAIREACTION, contentId, pageNumber, 59L, json);
		Thread.sleep(interval);
		json.put(MeetingManager.IS_BIG_FONT_SIZE, true);
    	meetingManager.sendWs(MeetingManager.CMD_QUESTIONNAIREACTION, contentId, pageNumber, 59L, json);
		Thread.sleep(interval);
		
		json = new JSONObject();
		json.put(MeetingManager.ALPHA, 0.3f);
    	meetingManager.sendWs(MeetingManager.CMD_QUESTIONNAIREACTION, contentId, pageNumber, 59L, json);
		Thread.sleep(interval);
		
    	meetingManager.sendWs(MeetingManager.CMD_CLOSEPOPUP, contentId, pageNumber, 59L, null); 
		Thread.sleep(interval);
		
		
    	meetingManager.sendWs(MeetingManager.CMD_ACTION, contentId, pageNumber, 110L, null); // 埋め込み動画
		Thread.sleep(10000);
		json = new JSONObject();
		json.put(MeetingManager.PLAY_TIME, 5);
    	meetingManager.sendWs(MeetingManager.CMD_MOVIEACTION, contentId, pageNumber, 110L, json);
		Thread.sleep(interval);
		json = new JSONObject();
		json.put(MeetingManager.TYPE, MeetingManager.PAUSE);
    	meetingManager.sendWs(MeetingManager.CMD_MOVIEACTION, contentId, pageNumber, 110L, json);
		Thread.sleep(interval);
		json.put(MeetingManager.TYPE, MeetingManager.START);
    	meetingManager.sendWs(MeetingManager.CMD_MOVIEACTION, contentId, pageNumber, 110L, json);
		Thread.sleep(interval);
		json = new JSONObject();
		json.put(MeetingManager.IS_FULL_SCREEN, true);
    	meetingManager.sendWs(MeetingManager.CMD_MOVIEACTION, contentId, pageNumber, 110L, json);
		Thread.sleep(interval);
		json = new JSONObject();
		json.put(MeetingManager.IS_FULL_SCREEN, true);
    	meetingManager.sendWs(MeetingManager.CMD_MOVIEACTION, contentId, pageNumber, 110L, json);
		Thread.sleep(interval);

    	meetingManager.sendWs(MeetingManager.CMD_ACTION, contentId, pageNumber, 109L, null); // 全画面Video(Videoボタン)
		Thread.sleep(interval);
		json = new JSONObject();
		json.put(MeetingManager.PLAY_TIME, 16);
    	meetingManager.sendWs(MeetingManager.CMD_MOVIEACTION, contentId, pageNumber, 109L, json);
		Thread.sleep(interval);
		json = new JSONObject();
		json.put(MeetingManager.TYPE, MeetingManager.PAUSE);
		json.put(MeetingManager.PLAY_TIME, 10);
    	meetingManager.sendWs(MeetingManager.CMD_MOVIEACTION, contentId, pageNumber, 109L, json);
		Thread.sleep(interval);
		json = new JSONObject();
		json.put(MeetingManager.TYPE, MeetingManager.START);
		json.put(MeetingManager.PLAY_TIME, 0);
    	meetingManager.sendWs(MeetingManager.CMD_MOVIEACTION, contentId, pageNumber, 109L, json);
		Thread.sleep(interval);
    	meetingManager.sendWs(MeetingManager.CMD_CLOSEPOPUP, contentId, pageNumber, 109L, null); 
		Thread.sleep(interval);

		pageNumber = 2;
    	meetingManager.sendWs(MeetingManager.CMD_MOVEPAGE, contentId, pageNumber, null, null); // 3ページへ
		Thread.sleep(interval);
    	meetingManager.sendWs(MeetingManager.CMD_ACTION, contentId, pageNumber, 116L, null); // 差替え画像
		Thread.sleep(interval);
    	meetingManager.sendWs(MeetingManager.CMD_ACTION, contentId, pageNumber, 117L, null);
		Thread.sleep(interval);
    	meetingManager.sendWs(MeetingManager.CMD_ACTION, contentId, pageNumber, 118L, null);
		Thread.sleep(interval);

		pageNumber = 3;
    	meetingManager.sendWs(MeetingManager.CMD_MOVEPAGE, contentId, pageNumber, null, null); // 4ページへ
		Thread.sleep(interval);
    	meetingManager.sendWs(MeetingManager.CMD_ACTION, contentId, pageNumber, 166L, null); // 差替え動画
		Thread.sleep(interval);
		
		json = new JSONObject();
		json.put(MeetingManager.IS_FULL_SCREEN, true);
    	meetingManager.sendWs(MeetingManager.CMD_MOVIEACTION, contentId, pageNumber, 166L, json);
		Thread.sleep(interval);

		json = new JSONObject();
		json.put(MeetingManager.TYPE, MeetingManager.PAUSE);
    	meetingManager.sendWs(MeetingManager.CMD_MOVIEACTION, contentId, pageNumber, 166L, json);
		Thread.sleep(interval);

		json = new JSONObject();
		json.put(MeetingManager.TYPE, MeetingManager.START);
    	meetingManager.sendWs(MeetingManager.CMD_MOVIEACTION, contentId, pageNumber, 166L, json);
		Thread.sleep(interval);
		
		json = new JSONObject();
		json.put(MeetingManager.IS_FULL_SCREEN, false);
    	meetingManager.sendWs(MeetingManager.CMD_MOVIEACTION, contentId, pageNumber, 166L, json);
		Thread.sleep(interval);
		
		json = new JSONObject();
		json.put(MeetingManager.PLAY_TIME, 5);
    	meetingManager.sendWs(MeetingManager.CMD_MOVIEACTION, contentId, pageNumber, 166L, json);
		Thread.sleep(interval);


		pageNumber = 4;
    	meetingManager.sendWs(MeetingManager.CMD_MOVEPAGE, contentId, pageNumber, null, null); // 5ページへ
		Thread.sleep(interval);
    	
		json = new JSONObject();
    	json.put(MeetingManager.FILE_NAME, "0035_0000000126_0000004256_RESOURCE.png"); // 3D
    	meetingManager.sendWs(MeetingManager.CMD_3DVIEWACTION, contentId, pageNumber, 2171L, json);
		Thread.sleep(interval);
    	json.put(MeetingManager.FILE_NAME, "0035_0000000121_0000004251_RESOURCE.png");
    	meetingManager.sendWs(MeetingManager.CMD_3DVIEWACTION, contentId, pageNumber, 2171L, json);
		Thread.sleep(interval);
    	json.put(MeetingManager.FILE_NAME, "0035_0000000123_0000004253_RESOURCE.png");
    	meetingManager.sendWs(MeetingManager.CMD_3DVIEWACTION, contentId, pageNumber, 2171L, json);
		Thread.sleep(interval);
    	json.put(MeetingManager.FILE_NAME, "0035_0000000124_0000004254_RESOURCE.png");
    	meetingManager.sendWs(MeetingManager.CMD_3DVIEWACTION, contentId, pageNumber, 2171L, json);
		Thread.sleep(interval);
    	json.put(MeetingManager.FILE_NAME, "0035_0000000126_0000004256_RESOURCE.png");
    	meetingManager.sendWs(MeetingManager.CMD_3DVIEWACTION, contentId, pageNumber, 2171L, json);
		Thread.sleep(interval);

		// PDFリンク
    	json = new JSONObject();
		json.put(MeetingManager.URL, "http://www.google.com/");
		json.put(MeetingManager.BROWSER, false);
    	meetingManager.sendWs(MeetingManager.CMD_LINKURLACTION, contentId, pageNumber, 0L, json);
		Thread.sleep(5000); // 手動で戻す　★objectIdがない
    	meetingManager.sendWs(MeetingManager.CMD_CLOSEPOPUP, contentId, pageNumber, 0L, null); 
		Thread.sleep(interval);

		// コンテンツリンク
		// (コンテンツOPENと同じ)
		
		// カーソル
		pageNumber = 0;
    	meetingManager.sendWs(MeetingManager.CMD_MOVEPAGE, contentId, pageNumber, null, null); // 1ページへ
		Thread.sleep(interval);
    	json = new JSONObject();
    	json.put(MeetingManager.IS_CURSOR_MODE, true);
    	meetingManager.sendWs(MeetingManager.CMD_CURSORMODE, contentId, pageNumber, null, json); // カーソルモード
		Thread.sleep(interval);
    	json = new JSONObject();
    	for (int i=0; i < 100; i++) {
    		json.put(MeetingManager.X, 256 + i * 5);
    		json.put(MeetingManager.Y, 263 + i * 5);
        	meetingManager.sendWs(MeetingManager.CMD_CURSOR, contentId, pageNumber, null, json);
    		Thread.sleep(50);
    	}
		Thread.sleep(interval);

    	// トップへ戻る
		meetingManager.sendWs(MeetingManager.CMD_TOBOOKSHELF, contentId, 0, null, null);
		Thread.sleep(interval);

		// NONEコンテンツ
		contentId = 1734;
		meetingManager.sendWs(MeetingManager.CMD_OPEN, contentId, 0, null, null);
		Thread.sleep(interval);
		meetingManager.sendWs(MeetingManager.CMD_TOBOOKSHELF, contentId, 0, null, null);
		Thread.sleep(interval);


		// 画像コンテンツ
		contentId = 1112;
		meetingManager.sendWs(MeetingManager.CMD_OPEN, contentId, 0, null, null);
		Thread.sleep(interval);
		meetingManager.sendWs(MeetingManager.CMD_TOBOOKSHELF, contentId, 0, null, null);
		Thread.sleep(interval);

		// HTMLコンテンツ
		contentId = 1177;
		meetingManager.sendWs(MeetingManager.CMD_OPEN, contentId, 0, null, null);
		Thread.sleep(interval);
		meetingManager.sendWs(MeetingManager.CMD_TOBOOKSHELF, contentId, 0, null, null);
		Thread.sleep(interval);

		// 映像コンテンツ
    	contentId = 1690L;
    	meetingManager.sendWs(MeetingManager.CMD_OPEN, contentId, 0, null, null);
		Thread.sleep(interval);
    	json = new JSONObject();
		json.put(MeetingManager.PLAY_TIME, 10);
    	meetingManager.sendWs(MeetingManager.CMD_MOVIEACTION, contentId, 0, null, json);
		Thread.sleep(interval);
    	json = new JSONObject();
		json.put(MeetingManager.TYPE, MeetingManager.PAUSE);
    	meetingManager.sendWs(MeetingManager.CMD_MOVIEACTION, contentId, 0, null, json);
		Thread.sleep(interval);
    	json = new JSONObject();
		json.put(MeetingManager.TYPE, MeetingManager.START);
    	meetingManager.sendWs(MeetingManager.CMD_MOVIEACTION, contentId, 0, null, json);
		Thread.sleep(interval);

		meetingManager.sendWs(MeetingManager.CMD_TOBOOKSHELF, contentId, 0, null, null);
		Thread.sleep(interval);

		// 音声コンテンツ
    	contentId = 1111;
    	meetingManager.sendWs(MeetingManager.CMD_OPEN, contentId, 0, null, null);
		Thread.sleep(interval);
    	json = new JSONObject();
		json.put(MeetingManager.PLAY_TIME, 10);
    	meetingManager.sendWs(MeetingManager.CMD_AUDIOACTION, contentId, 0, null, json);
		Thread.sleep(interval);
    	json = new JSONObject();
		json.put(MeetingManager.TYPE, MeetingManager.PAUSE);
    	meetingManager.sendWs(MeetingManager.CMD_AUDIOACTION, contentId, 0, null, json);
		Thread.sleep(interval);
    	json = new JSONObject();
		json.put(MeetingManager.TYPE, MeetingManager.START);
    	meetingManager.sendWs(MeetingManager.CMD_AUDIOACTION, contentId, 0, null, json);
		Thread.sleep(interval);
		meetingManager.sendWs(MeetingManager.CMD_TOBOOKSHELF, contentId, 0, null, null);
		Thread.sleep(interval);

		json = new JSONObject();
		json.put(MeetingManager.ID, "aaaaaaaaaa");
		json.put(MeetingManager.APPROVED, true);
//		json.put(MeetingManager.APPROVED, false);
		MeetingManager.getInstance().sendWs(MeetingManager.CMD_APPROVALSTATUS, null, null, null, json);
		
//		meetingManager.sendWs("{\"cmd\" : \"open\" , \"contentid\": 1135, \"pagenum\":11112}");

		}
		finally {
			meetingManager.deleteMeeting(meetingId, skey);
		}

		meetingManager.joinWebSocketClientThread();
		
	}

	private void subscribe() throws Exception {
		MeetingManager meetingManager = new MeetingManager();
		meetingManagerList.add(meetingManager);
		String skey = meetingManager.getSessionKey("1eba0e8f6fe874a9b86390bd1f8d0a47", "ts", true);
		log("skey = " + skey);
		meetingManager.join(meetingId , skey, null, true);
		
//		Thread.sleep(2000);
//		JSONObject json = new JSONObject();
//		json.put(MeetingManager.ID, skey);
//		json.put(MeetingManager.LOGIN_ID, "test");
//		meetingManager.sendWs(MeetingManager.CMD_PRESENTERREQUEST, null, null, null, json);

	}


}
