var port = 52532;

import Filter from 'badwords-ko';
var filter = new Filter();
import {faker} from '@faker-js/faker';
import * as _ from 'underscore';
import multer from 'multer';
import path from 'path';

import mysql, {} from 'mysql2';
var conn = mysql.createConnection({
	host: '127.0.0.1',
	user: 'web',
	password: '1q2w3e4r5t',
	database: 'test_nodam',
	port: 53306,
	multipleStatements: true,
});
conn.addListener('error', function (err){
	console.log(err);	
});

conn.query(`select word from fword where is_active = 1`, function (err_00, res_00){
	var arr_fword = [];
	_.each(res_00, function (v, i){
		arr_fword.push(v.word);
	});
	filter.addWords(...arr_fword);
	//console.log(filter.options.list.length);
});

import express from 'express';
var app = express();
app.use(express.json({limit: '2mb'}));
app.use(express.urlencoded({limit: '2mb', extended: false}));

/*
app.get('/', function (req, res, next){
	conn.query('select * from fword where is_active = 1 limit 10;', function (err_00, res_00){
		console.log(res_00);
		res.json(res_00);
	});
});
*/

/* DESC: 	입력받은 텍스트에서 비속어를 선별하고 * 처리하고 반환
 * URL:		http://121.150.20.121:52532/test_filter
 * METHOD:	POST
 *		|NAME		|TYPE		|DESC
 * INPUT:	|chat		|string		|채팅내용
 * OUTPUT:	|code		|int		|0: 성공, 이외 실패
 * 		|data		|string		|필터링된 채팅
 * 		|message	|string		|실패 사유 같은 것들
 */
app.post('/test_filter', function (req, res, next){
	console.log('/test_filter');
	console.log(req.body);
	var res_json = {code: 0, data: '', message: ''};
	try{
		var res_filt = filter.clean(req.body.chat);
		res_json.data = res_filt;
		res.send(res_json);
		return;
	}catch(err){
		res_json.code = 1;
		res.send(res_json); 
		return;
	}
});

/* DESC: 	회원 가입
 * URL:		http://121.150.20.121:52532/user_sign
 * METHOD:	POST
 *		|NAME		|TYPE		|DESC
 * INPUT:	|id		|string		|아이디, 8자 이상 16자 이하
 *		|pw		|string		|비밀번호, 8자 이상 16자 이하
 *		|name		|string		|이름
 *		|sex		|string		|성별, 0: 여자, 1: 남자
 * OUTPUT:	|code		|int		|0: 성공, 1: 실패 - 아이디 중복, 2: 실패 - insert failed, 99: 실패 - invalid param
 * 		|data		|int		|db에 저장된 index, 실패시 없음
 * 		|message	|string		|실패 사유 같은 것들
 */
app.post('/user_sign', function (req, res, next){
	console.log('/user_sign');
	console.log(req.body);
	var id = req.body.id;
	var pw = req.body.pw;
	var name = (req.body.name).trim();
	name = name.replace(/\+s/g, '');
	var sex = req.body.sex;
	var res_json = {code: 0, data: '', message: ''};
	if(!id || !pw || !name || (pw.length < 8 && pw.length > 16) || (id.length < 8 && pw.length > 16) || ((filter.clean(id)).indexOf('*') > -1) || ((filter.clean(name)).indexOf('*') > -1) || (id.indexOf(' ') > -1)){
		res_json.code = 99;
		res.send(res_json);
		return;
	}
	conn.query(`select * 
	from user 
	where id = ${conn.escape(id)}`, function (err_00, res_00){
		if(err_00 || (res_00.length > 0)){
			console.log(err_00);
			res_json.code = 1;
			res.send(res_json);
			return;
		}
		var query_insert = `insert into user(uid, id, pw, name, sex) values("${faker.string.uuid()}", ${conn.escape(id)}, ${conn.escape(pw)}, ${conn.escape(name)}, ${conn.escape(sex)})`;
		conn.query(query_insert, function (err_01, res_01){
			console.log(err_01);
			console.log(res_01);
			if(err_01){
				res_json.code = 2;
				res.send(res_json);
				return;
			}
			res_json.data = res_01.insertId;
			console.log(res_json);
			res.send(res_json);
			return;
		});
	});
});

/* DESC: 	회원 탈퇴
 * URL:		http://121.150.20.121:52532/user_resign
 * METHOD:	POST
 *		|NAME		|TYPE		|DESC
 * INPUT:	|id		|string		|아이디, 8자 이상 16자 이하
 *		|pw		|string		|비밀번호, 8자 이상 16자 이하
 * OUTPUT:	|code		|int		|0: 성공, 1: 실패 - 계정 없음, 2: 실패 - 탈퇴 실패, 99: 실패 - invalid param
 * 		|data		|int		|db에 저장된 index, 실패시 없음
 * 		|message	|string		|실패 사유 같은 것들
 */
app.post('/user_resign', function (req, res, next){
	console.log('/user_resign');
	console.log(req.body);
	var id = req.body.id;
	var pw = req.body.pw;
	var res_json = {code: 0, data: '', message: ''};
	if(!id || !pw){
		res_json.code = 99;
		res.send(res_json);
		return;
	}
	conn.query(`select * 
	from user 
	where id = ${conn.escape(id)} 
	and pw = ${conn.escape(pw)}`, function (err_00, res_00){
		if(err_00 || (res_00.length == 0)){
			console.log(err_00);
			res_json.code = 1;
			res.send(res_json);
			return;
		}
		console.log(res_00);
		var uid_u = res_00[0].uid;
		var query_update = `update user set is_active = 0 where uid = ${conn.escape(uid_u)}`;
		conn.query(query_update, function (err_01, res_01){
			if(err_01 || res_01.affectedRows == 0){
				console.log(err_01);
				res_json.code = 2;
				res.send(res_json);
				return;
			}
			res_json.data = res_01.affectedRows;
			console.log(res_json);
			res.send(res_json);
			return;
		});
	});
});

/* DESC: 	로그인
 * URL:		http://121.150.20.121:52532/user_login
 * METHOD:	POST
 * 		|NAME		|TYPE		|DESC
 * INPUT:	|id		|string		|아이디
 * 		|pw		|string		|비밀번호
 * OUTPUT:	|code		|int		|0: 성공, 1: 실패 - 아이디 존재 X 혹은 비번, 2: 미션 혹은 간판 오류, 3: 실패 - 회원 탈퇴됨
 * 		|data		|array		|
 * 		|-user		|json		|
 * 		|--uid		|string		|이용자 고유값
 * 		|--id		|string		|아이디
 * 		|--name		|string		|이름
 * 		|--sex		|int		|0: 여자, 1: 남자
 * 		|--costume	|int		|의상		기본값: 0(다 벗고 있는걸로 대충 적당히)
 * 		|--head		|int		|모자		기본값: 0(안쓴것?)
 * 		|--hair		|int		|머리카락	기본값: 0(대머리?)
 * 		|--face		|int		|얼굴		기본값: 0(기본얼굴?)
 * 		|--inventory	|json		|인벤토리	기본값: {"inven0":"0","inven1":"0","inven2":"0","inven3":"0"}
 * 		|---inven0~3	|int		|아이템
 * 		|-user_level	|json		|진행정도	기본값: {level: -1, level: 1, point: 0, process: 0}
 * 		|--uid		|string		|단계 고유값
 * 		|--level	|int		|진행 단계
 * 		|--point	|int		|획득 점수
 * 		|--process	|int		|해당 단계 진행도
 * 		|-user_sign	|json		|만든 간판	기본값: {uid: -1, data: -1, comment: ''}
 * 		|--uid		|string		|간판 고유값
 * 		|--data		|int		|표지판 그림
 * 		|--comment	|string		|표지판 표제어
 * 		|message	|string		|실패 사유 같은 것들
 */
app.post('/user_login', function (req, res, next){
	console.log('/user_login');
	console.log(req.body);
	var id = req.body.id;
	var pw = req.body.pw;
	var res_json = {code: 0, data: '', message: ''};
	if(!id || !pw){
		res_json.code = 99;
		res.send(res_json);
		return;
	}
	conn.query(`select uid, id, name, sex, costume, head, hair, face, inventory, is_active 
	from user 
	where id = "${req.body.id}" 
	and pw = "${req.body.pw}"`, function (err_00, res_00){
		if(err_00 || !res_00.length){
			res_json.code = 1;
			res.send(res_json);
			return;
		}
		if(res_00[0].is_active == 0){
			res_json.code = 3;
			res.send(res_json);
			return;
		}
		conn.query(`select uid, level, point, process 
		from user_level 
		where is_active = 1 
		and uid_u = "${res_00[0].uid}" 
		order by user_level.level desc;
		select uid, data, comment 
		from user_sign 
		where is_active = 1 
		and uid_u = "${res_00[0].uid}";`, function (err_01, res_01){
			if(err_01){
				res_json.code = 2;
				res.send(res_json);
				return;
			}
			res_00[0].inventory = JSON.parse(res_00[0].inventory);
			res_json.data = {
				user: (res_00[0]),
				user_level: res_01[0][0] || {level: 1, point: 0, process: 0},
				user_sign: res_01[1][0] || {uid: -1, data: -1, comment: ''},
			};
			console.log(res_json);
			res.send(res_json);
			return;
		});
	});
});

/* DESC: 	영상, 사운드, 그림 등 모든 미디어 데이터 호출
 * URL:		http://121.150.20.121:52532/get_media
 * METHOD:	POST
 *		|NAME		|TYPE		|DESC
 * INPUT:	|uid_u		|string		|이용자 고유값(무작위 접근 차단 용도)
 * OUTPUT:	|code		|int		|0: 성공, 1: 실패 - 계정 존재 X, 2: 실패 - 미디어 없음 or select failed, 99: 실패 - invalid param
 * 		|data		|array json	|
 * 		|-type		|int		|0: 영상, 1: 소리, 2: 그림
 * 		|-level		|int		|에셋이 사용되는 레벨(쓸데 있으면 사용)
 * 		|-path		|string		|데이터의 경로, 대체로 링크 형태가 될 것
 * 		|message	|string		|실패 사유 같은 것들
 */
app.post('/get_media', function (req, res, next){
	console.log('/get_media');
	console.log(req.body);
	var uid_u = req.body.uid_u;
	var res_json = {code: 0, data: '', message: ''};
	if(!uid_u){
		res_json.code = 99;
		res.send(res_json);
		return;
	}
	conn.query(`select * 
	from user 
	where uid = "${uid_u}"`, function (err_00, res_00){
		if(err_00 || !res_00.length){
			res_json.code = 1;
			res.send(res_json);
			return;
		}
		conn.query(`select media.type, media.level, media.path
		from media
		where is_active = 1
		order by media.level, media.type`, function (err_01, res_01){
			if(err_01 || !res_01.length){
				res_json.code = 2;
				res.send(res_json);
				return;
			}
			res_json.data = res_01;
			res.send(res_json);
			return;
		});
	});
});

/* DESC: 	이용자의 현재 진행 레벨과 누적 경험치(점수) 등을 획득
 * URL:		http://121.150.20.121:52532/get_user_level
 * METHOD:	POST
 *		|NAME		|TYPE		|DESC
 * INPUT:	|uid_u		|string		|이용자 고유값(무작위 접근 차단 용도)
 * OUTPUT:	|code		|int		|0: 성공, 1: 실패 - 계정 존재 X or select failed
 * 		|data		|array json	|기본값: {uid: -1, level: 0, point: 0, process: 0}
 * 		|-uid		|string		|레벨 고유값
 * 		|-level		|int		|현재 진행중인 레벨
 * 		|-process	|int		|현재 진행중인 레벨의 진행 정도(의미 없을 수 있음)
 * 		|-point		|int		|지금까지 획득한 누적 경험치
 * 		|message	|string		|실패 사유 같은 것들
 */
app.post('/get_user_level', function (req, res, next){
	console.log('/get_user_level');
	console.log(req.body);
	var uid_u = req.body.uid_u;
	var res_json = {code: 0, data: '', message: ''};
	if(!uid_u){
		res_json.code = 99;
		res.send(res_json);
		return;
	}
	conn.query(`select * 
	from user
	where uid = "${uid_u}";
	select level, point, process 
	from user_level 
	where is_active = 1 
	and uid_u = "${uid_u}" 
	order by user_level.level desc`, function (err_00, res_00){
		if(err_00 || !res_00[0].length){
			res_json.code = 1;
			res.send(res_json);
			return;
		}
		res_json.data = res_00[1] || [{uid: -1, level: 0, point: 0, process: 0}];
		res.send(res_json);
		return;
	});
});

/* DESC: 	이용자의 레벨 진행 정보 등록 혹은 갱신
 * URL:		http://121.150.20.121:52532/update_user_level
 * METHOD:	POST
 *		|NAME		|TYPE		|DESC
 * INPUT:	|uid_u		|string		|이용자 고유값(무작위 접근 차단 용도)
 * 		|point		|int		|획득한 점수
 * 		|process	|int		|진행도 
 * OUTPUT:	|code		|int		|0: 성공, 1: 실패 - 계정 존재 X or select failed, 2: 실패 - insert or update failed
 * 		|data		|int		|0: 갱신 혹은 등록 실패, 1: 갱신 혹은 등록 성공
 * 		|message	|string		|실패 사유 같은 것들
 */
app.post('/update_user_level', function (req, res, next){
	console.log('/update_user_level');
	console.log(req.body);
	var uid_u = req.body.uid_u;
	var level = req.body.level || 1;
	var point = req.body.point || 0;
	var process = req.body.process || 0;
	var res_json = {code: 0, data: '', message: ''};
	if(!uid_u){
		res_json.code = 99;
		res.send(res_json);
		return;
	}
	conn.query(`select * 
	from user
	where uid = "${uid_u}";
	select * 
	from user_level 
	where is_active = 1 
	and uid_u = "${uid_u}"`, function (err_00, res_00){
		if(err_00 || !res_00[0].length){
			res_json.code = 1;
			res.send(res_json);
			return;
		}
		var query_str = `insert into user_level(uid, uid_u, level, point, process)
		values("${faker.string.uuid()}", "${uid_u}", "${level}", "${point}", "${process}")`;
		if(res_00[1].length){
			query_str = `update user_level 
			set level = "${level}", point = "${point}", process = "${process}" 
			where uid_u = "${uid_u}"`;
		}
		conn.query(query_str, function (err_01, res_01){
			if(err_01){
				res_json.code = 2;
				res.send(res_json);
				return;
			}
			res_json.data = res_01.affectedRows;
			res.send(res_json);
			return;
		});
	});
});

/* DESC: 	이용자의 레벨 진행 정보 초기화
 * URL:		http://121.150.20.121:52532/reset_user_level
 * METHOD:	POST
 *		|NAME		|TYPE		|DESC
 * INPUT:	|uid_u		|string		|이용자 고유값
 * OUTPUT:	|code		|int		|0: 성공, 1: 실패 - 계정 없음 or 레벨 없음, 2: 실패 - update failed
 * 		|data		|int		|0: 갱신 실패, >= 1: 갱신 성공
 * 		|message	|string		|실패 사유 같은 것들
 */
app.post('/reset_user_level', function (req, res, next){
	console.log('/del_user_level');
	console.log(req.body);
	var uid_u = req.body.uid_u;
	var res_json = {code: 0, data: '', message: ''};
	if(!uid_u){
		res_json.code = 99;
		res.send(res_json);
		return;
	}
	conn.query(`select *
	from user
	where uid = "${uid_u}";
	select * 
	from user_level 
	where uid_u = "${uid_u}";
	update user_level
	set is_active = 0
	where uid_u = "${uid_u}"`, function (err_00, res_00){
		console.log(res_00);
		if(err_00 || !res_00[0].length || !res_00[1].length){
			res_json.code = 1;
			res.send(res_json);
			return;
		}
		res_json.data = res_00[2].affectedRows;
		res.send(res_json);
		return;
	});
});

/* DESC: 	이용자의 코스튬 정보 갱신
 *		이름이 빈칸이면 오류 반환
 * URL:		http://121.150.20.121:52532/update_user_costume
 * METHOD:	POST
 *		|NAME		|TYPE		|DESC
 * INPUT:	|uid_u		|string		|이용자 고유값
 * 		|head		|int		|대갈통
 * 		|hair		|int		|머리스타일
 * 		|face		|int		|와꾸
 * 		|costume	|int		|의상
 * 		|sex		|int		|성별
 * 		|name		|string		|이름
 * OUTPUT:	|code		|int		|0: 성공, 1: 실패 - 계정 없음, 2: 실패 - update failed
 * 		|data		|int		|0: 갱신 실패, >= 1: 갱신 성공
 * 		|message	|string		|실패 사유 같은 것들
 */
app.post('/update_user_costume', function (req, res, next){
	console.log('/update_user_costume');
	console.log(req.body);
	var uid_u = req.body.uid_u;
	var head = req.body.head;
	var hair = req.body.hair;
	var face = req.body.face;
	var costume = req.body.costume;
	var sex = req.body.sex;
	var name = req.body.name;
	var res_json = {code: 0, data: '', message: ''};
	if(!uid_u || (name.length < 0) || ((filter.clean(name)).indexOf('\*') > 0)){
		res_json.code = 99;
		res.send(res_json);
		return;
	}
	conn.query(`select * 
	from user 
	where uid = "${uid_u}";`, function (err_00, res_00){
		if(err_00 || !res_00.length){
			res_json.code = 1;
			res.send(res_json);
			return;
		}
		conn.query(`update user 
		set head = "${head}", hair = "${hair}", face = "${face}", costume = "${costume}", sex = "${sex}", name = ${conn.escape(name)} 
		where uid = ${conn.escape(uid_u)}`, function (err_01, res_01){
			if(err_01){
				res_json.code = 2;
				res.send(res_json);
				return;
			}
			res_json.data = res_01.affectedRows;
			res.send(res_json);
			return;
		});
	});
});

/* DESC: 	이용자 정보 획득
 * URL:		http://121.150.20.121:52532/get_user
 * METHOD:	POST
 *		|NAME		|TYPE		|DESC
 * INPUT:	|uid_u		|string		|이용자 고유값
 * OUTPUT:	|code		|int		|0: 성공, 1: 실패 - 계정 없음, 2: 실패 - update failed
 * 		|data		|		|
 * 		|-user		|json		|
 * 		|--uid		|string		|이용자 고유값
 * 		|--id		|string		|아이디
 * 		|--name		|string		|이름
 * 		|--sex		|int		|0: 여자, 1: 남자
 * 		|--costume	|int		|의상		기본값: 0(다 벗고 있는걸로 대충 적당히)
 * 		|--head		|int		|모자		기본값: 0(안쓴것?)
 * 		|--hair		|int		|머리카락	기본값: 0(대머리?)
 * 		|--face		|int		|얼굴		기본값: 0(기본얼굴?)
 * 		|--inventory	|json		|인벤토리	기본값: {"inven0":"0","inven1":"0","inven2":"0","inven3":"0"}
 * 		|---inven0~3	|int		|아이템
 * 		|-user_level	|json		|진행정도	기본값: {level: -1, level: 1, point: 0, process: 0}
 * 		|--uid		|string		|단계 고유값
 * 		|--level	|int		|진행 단계
 * 		|--point	|int		|획득 점수
 * 		|--process	|int		|해당 단계 진행도
 * 		|-user_sign	|json		|만든 간판	기본값: {uid: -1, data: -1, comment: ''}
 * 		|--uid		|string		|표지판 고유값
 * 		|--data		|int		|표지판 그림
 * 		|--comment	|string		|표지판 표제어
 * 		|message	|string		|실패 사유 같은 것들
 */
app.post('/get_user', function (req, res, next){
	console.log('/get_user_by_uid');
	console.log(req.body);
	var uid_u = req.body.uid_u;
	var res_json = {code: 0, data: '', message: ''};
	if(!uid_u){
		res_json.code = 99;
		res.send(res_json);
		return;
	}
	conn.query(`select uid, id, name, sex, costume, head, hair, face, inventory 
	from user 
	where uid = "${uid_u}"`, function (err_00, res_00){
		if(err_00 || !res_00.length){
			res_json.code = 1;
			res.send(res_json);
			return;
		}
		conn.query(`select uid, level, point, process 
		from user_level 
		where uid_u = "${res_00[0].uid}";
		select uid, data, comment 
		from user_sign 
		where uid_u = "${res_00[0].uid}";`, function (err_01, res_01){
			if(err_01){
				res_json.code = 2;
				res.send(res_json);
				return;
			}
			res_00[0].inventory = JSON.parse(res_00[0].inventory);
			res_json.data = {
				user: (res_00[0]),
				user_level: res_01[0][0] || {level: 1, point: 0, process: 0},
				user_sign: res_01[1][0] || {uid: -1, data: -1, comment: ''},
			};
			console.log(res_json);
			res.send(res_json);
			return;
		});
	});
});

/* DESC: 	이용자의 인벤토리 내용물 변경
 *		item = 0 일 때, 아이템 없음으로 취급
 * URL:		http://121.150.20.121:52532/set_inventory
 * METHOD:	POST
 *		|NAME		|TYPE		|DESC
 * INPUT:	|uid_u		|string		|이용자 고유값
 * 		|slot		|int		|인벤토리칸, 0~3
 * 		|item		|int		|아이템 종류, 0~4(임시)
 * OUTPUT:	|code		|int		|0: 성공, 1: 실패 - 계정 없음, 2: 실패 - update failed
 * 		|data		|int		|0: 갱신 실패, >= 1: 갱신 성공
 * 		|message	|string		|실패 사유 같은 것들
 */
app.post('/set_inventory', function (req, res, next){
	console.log('/set_inventory');
	console.log(req.body);
	var uid_u = req.body.uid_u;
	var slot = req.body.slot | 0;
	var item = req.body.item | 0;
	var res_json = {code: 0, data: '', message: ''};
	if(!uid_u || !(0 <= slot && slot < 4) || !(0 <= item && item < 5)){
		res_json.code = 99;
		res.send(res_json);
		return;
	}
	conn.query(`select inventory 
	from user 
	where uid = ${conn.escape(uid_u)}`, function (err_00, res_00){
		if(err_00 || !res_00.length){
			res_json.code = 1;
			res.send(res_json);
			return;
		}
		var json_inven = JSON.parse(res_00[0].inventory);
		if(slot == 0) json_inven.inven0 = item;
		if(slot == 1) json_inven.inven1 = item;
		if(slot == 2) json_inven.inven2 = item;
		if(slot == 3) json_inven.inven3 = item;
		var string_inven = JSON.stringify(json_inven);
		conn.query(`update user 
		set inventory = ${conn.escape(string_inven)}
		where uid = ${conn.escape(uid_u)}`, function (err_01, res_01){
			if(err_01){
				res_json.code = 2;
				res.send(res_json);
				return;
			}
			res_json.data = res_01.affectedRows;
			res.send(res_json);
			return;
		});
	});
});

/* DESC: 	이용자의 인벤토리 초기화
 *		초기값은 {"inven0":0,"inven1":0,"inven2":0,"inven3":0}
 * URL:		http://121.150.20.121:52532/reset_inventory
 * METHOD:	POST
 *		|NAME		|TYPE		|DESC
 * INPUT:	|uid_u		|string		|이용자 고유값
 * OUTPUT:	|code		|int		|0: 성공, 1: 실패 - update failed
 * 		|data		|int		|0: 갱신 실패, >= 1: 갱신 성공
 * 		|message	|string		|실패 사유 같은 것들
 */
 app.post('/reset_inventory', function (req, res, next){
	console.log('/reset_inventory');
	console.log(req.body);
	var uid_u = req.body.uid_u;
	var res_json = {code: 0, data: '', message: ''};
	if(!uid_u){
		res_json.code = 99;
		res.send(res_json);
		return;
	}
	conn.query(`update user 
	set inventory = '{"inven0":0,"inven1":0,"inven2":0,"inven3":0}' 
	where uid = ${conn.escape(uid_u)}`, function (err_00, res_00){
		if(err_00){
			console.log(err_00);
			res_json.code = 1;
			res.send(res_json);
			return;
		}
		res_json.data = res_00.affectedRows;
		res.send(res_json);
		return;
	});
});

/* DESC: 	이용자의 인벤토리 정보 획득
 * URL:		http://121.150.20.121:52532/get_inventory
 * METHOD:	POST
 *		|NAME		|TYPE		|DESC
 * INPUT:	|uid_u		|string		|이용자 고유값
 * OUTPUT:	|code		|int		|0: 성공, 1: 실패 - 계정 없음
 * 		|data		|json		|
 * 		||inven0	|int		|아이템 종류 0~4
 * 		||inven1	|int		|아이템 종류 0~4
 * 		||inven2	|int		|아이템 종류 0~4
 * 		||inven3	|int		|아이템 종류 0~4
 * 		|message	|string		|실패 사유 같은 것들
 */
app.post('/get_inventory', function (req, res, next){
	console.log('/get_inventory');
	console.log(req.body);
	var uid_u = req.body.uid_u;
	var res_json = {code: 0, data: '', message: ''};
	if(!uid_u){
		res_json.code = 99;
		res.send(res_json);
		return;
	}
	conn.query(`select inventory 
	from user 
	where uid = ${conn.escape(uid_u)}`, function (err_00, res_00){
		if(err_00 || !res_00.length){
			res_json.code = 1;
			res.send(res_json);
			return;
		}
		res_json.data = JSON.parse(res_00[0].inventory);
		res.send(res_json);
		return;
	});
});

/* DESC: 	이용자가 미션을 시작했다고 알림
 * 		반환되는 uid_m을 통해 이용자의 미션 고유값 판단
 * URL:		http://121.150.20.121:52532/set_mission
 * METHOD:	POST
 *		|NAME		|TYPE		|DESC
 * INPUT:	|uid_u		|string		|이용자 고유값
 * 		|level		|string		|이용자 고유값
 * OUTPUT:	|code		|int		|0: 성공, 1: insert failed
 * 		|data		|json		|
 * 		||uid_m		|string		|미션 고유값
 * 		|message	|string		|실패 사유 같은 것들
 */
app.post('/set_mission', function (req, res, next){
	console.log('/set_mission');
	console.log(req.body);
	var res_json = {code: 0, data: {}, message: ''};
	var uid_u = req.body.uid_u;
	var level = req.body.level;
	var uid_m = faker.string.uuid();
	if(!uid_u){
		res_json.code = 99;
		res.send(res_json);
		return;
	}
	conn.query(`update user_level 
	set is_active = 0 
	where uid_u = ${conn.escape(uid_u)} 
	and level = ${conn.escape(level)};
	insert into user_level(uid, uid_u, level) 
	values("${uid_m}", ${conn.escape(uid_u)}, ${conn.escape(level)});`, function (err_00, res_00){
		if(err_00){
			console.log(err_00);
			res_json.code = 1;
			res.send(res_json);
			return;
		}
		res_json.data = {
			uid_m: uid_m
		};
		res.send(res_json);
		return;
	});
});

/* DESC: 	미션 고유값을 기반으로 미션 정보 갱신
 * 		점수는 현재까지 누적된 값을 전송해주면 됨
 * URL:		http://121.150.20.121:52532/update_mission
 * METHOD:	POST
 *		|NAME		|TYPE		|DESC
 * INPUT:	|uid_m		|string		|미션 고유값
 * 		|point		|int		|누적 획득 점수
 * 		|process	|int		|진행률, 현재는 쓸 일 없음, 기본값 0
 * OUTPUT:	|code		|int		|0: 성공, 1: update failed
 * 		|data		|json		|
 * 		|message	|string		|실패 사유 같은 것들
 */
app.post('/update_mission', function (req, res, next){
	console.log('/update_mission');
	console.log(req.body);
	var res_json = {code: 0, data: {}, message: ''};
	var uid_m = req.body.uid_m;
	var point = req.body.point;
	var process = req.body.process || '0';
	if(!uid_m){
		res_json.code = 99;
		res.send(res_json);
		return;
	}
	conn.query(`update user_level 
	set point = ${conn.escape(point)}, 
	process = ${conn.escape(process)} 
	where uid = ${conn.escape(uid_m)}`, function (err_00, res_00){
		if(err_00){
			console.log(err_00);
			res_json.code = 1;
			res.send(res_json);
			return;
		}
		res.send(res_json);
		return;
	});
});

/* DESC: 	이용자 고유값을 통해 모든 미션을 초기화
 * URL:		http://121.150.20.121:52532/reset_mission
 * METHOD:	POST
 *		|NAME		|TYPE		|DESC
 * INPUT:	|uid_u		|string		|이용자 고유값
 * OUTPUT:	|code		|int		|0: 성공, 1: update failed
 * 		|data		|json		|-
 * 		|message	|string		|실패 사유 같은 것들
 */
app.post('/reset_mission', function (req, res, next){
	console.log('/reset_mission');
	console.log(req.body);
	var uid_u = req.body.uid_u;
	var res_json = {code: 0, data: {}, message: ''};
	if(!uid_u){
		res_json.code = 99;
		res.send(res_json);
		return;
	}
	conn.query(`update user_level 
	set is_active = 0 
	where uid_u = ${conn.escape(uid_u)}`, function (err_00, res_00){
		if(err_00){
			res_json.code = 1;
			res.send(res_json);
			return;
		}
		res.send(res_json);
		return;
	});
});

/* DESC: 	각 미션에 해당하는 질문/답변/해설 등을 받아 옴
 * URL:		http://121.150.20.121:52532/get_question
 * METHOD:	POST
 *		|NAME		|TYPE		|DESC
 * INPUT:	|uid_u		|string		|이용자 고유값
 * OUTPUT:	|code		|int		|0: 성공, 1: select failed
 * 		|data		|json		|
 * 		|-level		|int		|미션 넘버
 * 		|-type		|int		|0: 시험 문제, 이것만 보냄
 * 		|-question	|string		|시험 문제
 * 		|-answers	|array json	|
 * 		||-a		|string		|답변
 * 		||-c		|int		|if type == 0, 	0: 오답, 1: 정답
 * 		||		|		|else,		점수(설문)
 * 		|-explain	|string		|해설
 * 		|message	|string		|실패 사유 같은 것들
 */ 
app.post('/get_question', function (req, res, next){
	console.log('/get_question');
	console.log(req.body);
	var uid_u = req.body.uid_u;
	var res_json = {code: 0, data: '', message: ''};
	if(!uid_u){
		res_json.code = 99;
		res.send(res_json);
		return;
	}
	conn.query(`select q.level, q.type, q.question, q.answers, q.explain 
	from question as q 
	where q.is_active = 1 
	and q.type = 0`, function (err_00, res_00){
		//console.log(res_00);
		if(err_00 ||(res_00.length == 0)){
			res_json.code = 1;
			res.send(res_json);
			return;	
		}
		for(var i = 0; i < res_00.length; i++){
			res_00[i].answers = JSON.parse(res_00[i].answers);
		}
		res_json.data = res_00;
		console.log(res_json);
		res.send(res_json);
		return;
	});
;})

/*
간판 점유 기능
간판 점유 여부 확인 기능
- 간판 점유 남은 시간 반환 기능

스크린샷 저장 기능 -> 서버에 png 파일을 저장하는 방법에 대해

설문조사 불러오기
설문조사 결과 저장
- json 형태로 저장하되 문제의 개수 및 선택한 답변의 점수 표시
- 총점 저장

이용약관
http://121.150.20.121:52530/terms_of_service.html

개인정보보호정책
http://121.150.20.121:52530/privacy_policy.html
*/

var upload = multer({
	storage: multer.diskStorage({
		destination: function (req, file, done){
			done(null, 'uploads/');
		},
		filename: function (req, file, done){
			var ext = path.extname(file.originalname);
			var filename = path.basename(file.originalname, ext) + ext;
			done(null, filename);
		}
	}),
	limits: {
		fileSize: 2 * 1024 * 1024,
	}
});

//app.get('/test_upload', function (req, res, next){
//	res.sendFile('C:/jamong/240722_server_test/test_upload.html');
//});

app.get('/get_image', function (req, res, next){
	res.sendFile(`/home/ubuntu/node/uploads/${req.query.uid_u}.png`);
});

/* DESC: 	스크린샷을 서버에 저장하고 서버상 경로, 파일 크기 및 db상 인덱스 반환
 *		파일의 필드네임은 file_image
 *		파일 이름은 uid_u(이용자 고유값을 사용할 것을 권장)
 *		파일의 확장자는 반드시 png로 설정할 것
 * URL:		http://121.150.20.121:52532/set_image
 * METHOD:	POST
 *		|NAME		|TYPE		|DESC
 * INPUT:	|file_image	|file		|{이용자 고유값}.png
 * OUTPUT:	|code		|int		|0: 성공, 1: update or insert failed
 * 		|data		|json		|
 * 		|-insert_id	|int		|db상 인덱스, 0 초과시 정상
 * 		|-path		|string		|서버상 데이터 저장 경로
 * 		|-size		|int		|파일 크기
 * 		|message	|string		|실패 사유 같은 것들
 */
app.post('/set_image', upload.single('file_image'), function (req, res, next){
	console.log('/set_image');
	console.log(req.file);
	var path = req.file.path;
	var size = req.file.size;
	var filename = req.file.filename;
	var uid_u = filename.split('.')[0];
	var res_json = {code: 0, data: {
		insert_id: 0,
		path: path,
		size: size,
	}, message: ''};
	conn.query(`update user_screenshot set is_active = 0 where uid_u = ${conn.escape(uid_u)};
	insert into user_screenshot(uid_u) values(${conn.escape(uid_u)});`, function (err_00, res_00){
		if(err_00){
			console.log(err_00);
			res_json.code = 1;
			res.send(res_json);
			return;
		}
		res_json.data.insert_id = res_00[1].insertId;
		res.send(res_json);
		return;
	});
});

/* DESC: 	새로운 설문조사 결과를 저장
 * URL:		http://121.150.20.121:52532/set_user_survey
 * METHOD:	POST
 *		|NAME		|TYPE		|DESC
 * INPUT:	|uid_u		|string		|이용자 고유값
 * 		|a0		|int		|첫번째 답변 점수
 * 		|a1		|int		|두번째 답변 점수
 * 		|a2		|int		|세번째 답변 점수
 * 		|amount		|int		|모든 답변 점수 총합
 * OUTPUT:	|code		|int		|0: 성공, 1: update or insert failed
 * 		|data		|json		|
 * 		|-uid_us	|string		|표지판 고유값
 * 		|message	|string		|실패 사유 같은 것들
 */
app.post('/set_user_survey', function (req, res, next){
	console.log('/set_user_survey');
	console.log(req.body);
	var uid_u = req.body.uid_u;
	var a0 = req.body.a0;
	var a1 = req.body.a1;
	var a2 = req.body.a2;
	var amount = req.body.amount;
	var res_json = {code: 0, data: {}, message: ''};
	if(!uid_u){
		res_json.code = 99;
		res.send(res_json);
		return;
	}
	var answers = {
		a0: a0,
		a1: a1,
		a2: a2,
	};
	conn.query(`update user_survey 
	set is_active = 0 
	where uid_u = ${conn.escape(uid_u)};
	insert into user_survey(uid_u, answers, amount) 
	values(${conn.escape(uid_u)}, ${conn.escape(JSON.stringify(answers))}, ${amount});`, function (err_00, res_00){
		if(err_00){
			console.log(err_00);
			res_json.code = 1;
			res.send(res_json);
			return;
		}
		res_json.data = res_00[1].insertId;
		res.send(res_json);
		return;
	});
});

/* DESC: 	설문조사 질문지들을 모두 받아옴
 *		답변 텍스트 및 점수는 모두 통일할 예정
 *		퀴즈와는 달리 정답이 존재하는게 아니라, 누적시킬 점수만 존재함
 * URL:		http://121.150.20.121:52532/get_survey
 * METHOD:	POST
 *		|NAME		|TYPE		|DESC
 * INPUT:	|uid_u		|string		|이용자 고유값
 * OUTPUT:	|code		|int		|0: 성공, 1: select failed
 * 		|data		|json		|
 * 		|-question	|string		|표지판 고유값
 * 		|-answers	|array json	|
 * 		|--a		|string		|답변 텍스트
 * 		|--c		|string		|좋지 않다: 0, 보통이다: 1, 좋다: 2
 * 		|message	|string		|실패 사유 같은 것들
 */
app.post('/get_survey', function (req, res, next){
	console.log('/get_survey');
	console.log(req.body);
	var uid_u = req.body.uid_u;
	var res_json = {code: 0, data: {}, message: ''};
	if(!uid_u){
		res_json.code = 99;
		res.send(res_json);
		return;
	}
	conn.query(`select question, answers from question where type = 1 and is_active = 1`, function (err_00, res_00){
		if(err_00 || (res_00.length == 0)){
			console.log(err_00);
			res_json.code = 1;
			res.send(res_json);
			return;
		}
		res_json.data = res_00;
		for(var i = 0; i < (res_json.data).length; i++){
			res_json.data[i].answers = JSON.parse(res_json.data[i].answers);
		}
		res.send(res_json);
		return;
	});
});

/* DESC: 	새로운 표지판을 저장하고 해당하는 고유값을 반환
 * URL:		http://121.150.20.121:52532/set_user_sign
 * METHOD:	POST
 *		|NAME		|TYPE		|DESC
 * INPUT:	|uid_u		|string		|이용자 고유값
 * 		|data		|int		|클라이언트상 표지판의 번호
 * 		|comment	|string		|표지판 표제어
 * OUTPUT:	|code		|int		|0: 성공, 1: update or insert failed, 2: 표제어 필터링됨
 * 		|data		|json		|
 * 		|-uid_us	|string		|표지판 고유값
 * 		|message	|string		|실패 사유 같은 것들
 */
app.post('/set_user_sign', function (req, res, next){
	console.log('/set_user_sign');
	console.log(req.body);
	var uid_u = req.body.uid_u;
	var data = req.body.data;
	var comment = req.body.comment;
	var res_json = {code: 0, data: {}, message: ''};
	if(!uid_u){
		res_json.code = 99;
		res.send(res_json);
		return;
	}
	if(((filter.clean(comment)).indexOf('*') > -1)){
		res_json.code = 2;
		res.send(res_json);
		return;
	}
	var uid = faker.string.uuid();
	conn.query(`update user_sign 
	set is_active = 0 
	where uid_u = ${conn.escape(uid_u)};
	insert into user_sign(uid, uid_u, data, comment) 
	values(${conn.escape(uid)}, ${conn.escape(uid_u)}, ${conn.escape(data)}, ${conn.escape(comment)});`, function (err_00, res_00){
		if(err_00){
			console.log(err_00);
			res_json.code = 1;
			res.send(res_json);
			return;
		}
		res_json.data = {
			uid_us: uid
		};
		res.send(res_json);
		return;
	});
});

/* DESC: 	이용자의 간판을 불러옴
 * URL:		http://121.150.20.121:52532/get_user_sign
 * METHOD:	POST
 *		|NAME		|TYPE		|DESC
 * INPUT:	|uid_u		|string		|이용자 고유값
 * OUTPUT:	|code		|int		|0: 성공, 1: select failed
 * 		|data		|json		|
 * 		|-uid		|string		|표지판 고유값
 * 		|-data		|int		|표지판 그림
 * 		|-comment	|string		|표지판 표제어
 * 		|message	|string		|실패 사유 같은 것들
 */
app.post('/get_user_sign', function (req, res, next){
	console.log('/get_user_sign');
	console.log(req.body);
	var uid_u = req.body.uid_u;
	var res_json = {code: 0, data: {}, message: ''};
	if(!uid_u){
		res_json.code = 99;
		res.send(res_json);
		return;
	}
	conn.query(`select uid, data, comment from user_sign where uid_u = ${conn.escape(uid_u)} and is_active = 1`, function (err_00, res_00){
		if(err_00 || (res_00.length == 0)){
			res_json.code = 1;
			res.send(res_json);
			return;
		}
		res_json.data = res_00[0];
		res.send(res_json);
		return;
	});
});

app.get('/get_test', function (req, res, next){
	conn.query('select * from user where id="safaquiel"', function (err_00, res_00){
		if(err_00){
			res.send(err_00);
		}
		res.send(res_00);
	});
});

app.get('/test_chat', function (req, res, next){
	console.log('/test_chat');
	console.log(req.query);
	res.sendFile('C:/jamong/240722_server_test/test_socket_chat.html');
});

// 쓰레기 자동 삭제 및 생성
setInterval(function (){
	conn.query('select 1');
	console.log('database handshake');
}, 180000);

app.listen(port, function (){
	console.log(port);
});



/*
import {WebSocketServer} from 'ws';
const sockserver = new WebSocketServer({ port: 52534 })
sockserver.on('connection', ws => {
	console.log('New client connected!')
	ws.send('connection established')
	ws.on('close', () => console.log('Client has disconnected!'))
	ws.on('message', data => {
		sockserver.clients.forEach(client => {
			console.log(`distributing message: ${data}`)
			client.send(`${data}`)
		})
	})
	ws.onerror = function () {
		console.log('websocket error')
	}

	ws.on('jump', function (data){
		console.log(data);
		client.send('jump', data);
	});
});
*/
