'use strict';

const apiResult = require('./api-result');
const resHelper = require('./response-helper');
const type = require('./type');

const _routes = [];
let _app;

/**
 * このモジュールを初期化します
 *
 * @param  {any} app 対象のサーバアプリケーション
 */
var init = app => {
	if (app === null)
		throw new Error('routes is unknown type');

	_app = app;

	return this;
};
module.exports = init;

/**
 * ルートを追加します
 *
 * @param  {string[]} route
 * @param  {Function[]} middles
 */
var addRoute = (route, middles) => {
	if (!Array.isArray(route) || route === undefined)
		throw new Error('routes is unknown type');

	if (middles === undefined)
		middles = [];

	var method = route[0];
	const path = route[1];
	var extensions = route[2];

	method = method.replace(/^del$/, 'delete');

	require('methods').forEach(m => {
		if (method.toLowerCase() === m) {
			middles.forEach(middle => {
				_app[m](path, middle);
			});

			_app[m](path, (request, response) => {
				resHelper(response);
				var dirPath = '../routes';

				path.substring(1).split(/\//).forEach((seg, i) => {
					dirPath += '/' + seg.replace(/:/, '');
				});

				(async () => {
					const result = await require(dirPath)[m](request.body, extensions);
					response.success(result);
				})().catch(err => {
					if (type(err) !== 'Error')
						response.error(err);
					else
					{
						console.log(`Internal Error: ${err.stack}`);
						response.error(apiResult(500, 'internal error'));
					}
				});
			});

			_routes.push({method: m.toUpperCase(), path: path, extensions: extensions});
		}
	});
}
exports.addRoute = addRoute;

/**
 * 複数のルートを追加します
 *
 * @param  {string[][]} routes
 * @param  {Function[]} middles
 */
var addRoutes = (routes, middles) => {
	if (!Array.isArray(routes) || routes === undefined)
		throw new Error('routes is unknown type');

	routes.forEach(route => addRoute(route, middles));
};
exports.addRoutes = addRoutes;

/**
 * 該当するルートを取得します
 *
 * @param  {string} method
 * @param  {string} path
 * @return {Object} ルート情報
 */
var findRoute = (method, path) => {
	var result;

	_routes.some((route) => {
		if (method === route.method && path === route.path)
		{
			result = route;
			return true;
		}
	});

	return result;
};
exports.findRoute = findRoute;

@@ -929,24 +929,47 @@
 ponse) =%3E %7B%0A
+%09%09%09%09console.log(path);%0A
 %09%09%09%09resHelpe
@@ -981,16 +981,16 @@
 ponse);%0A
-
 %09%09%09%09var 
@@ -1130,23 +1130,184 @@
 %09%09%09%09
-(async () =%3E %7B%0A
+const route = require(dirPath)%5Bm%5D;%0A%0A%09%09%09%09try %7B%0A%09%09%09%09%09(async () =%3E %7B%0A%09%09%09%09%09%09if (route == undefined)%0A%09%09%09%09%09%09%09throw new Error('endpoint not found%5Cntarget: ' + method + ' ' + path);%0A%0A%09
 %09%09%09%09
@@ -1376,24 +1376,25 @@
 ions);%0A%09%09%09%09%09
+%09
 response.suc
@@ -1411,16 +1411,17 @@
 t);%0A%09%09%09%09
+%09
 %7D)().cat
@@ -1428,24 +1428,25 @@
 ch(err =%3E %7B%0A
+%09
 %09%09%09%09%09if (typ
@@ -1467,24 +1467,25 @@
 ror')%0A%09%09%09%09%09%09
+%09
 response.err
@@ -1502,13 +1502,15 @@
 %09%09%09%09
+%09
 else%0A
+%09
 %09%09%09%09
@@ -1514,24 +1514,25 @@
 %09%09%09%09%7B%0A%09%09%09%09%09%09
+%09
 console.log(
@@ -1564,16 +1564,17 @@
 ack%7D%60);%0A
+%09
 %09%09%09%09%09%09re
@@ -1617,20 +1617,43 @@
 l error'
+, %7Bdetails: err.stack%7D
 ));%0A
+%09
 %09%09%09%09%09%7D%0A%09
@@ -1655,20 +1655,194 @@
 %09%09%7D%0A%09%09%09%09
+%09
 %7D);%0A
+%09%09%09%09%7D%0A%09%09%09%09catch (err) %7B%0A%09%09%09%09%09console.log(%60Internal Error (Async): $%7Berr.stack%7D%60);%0A%09%09%09%09%09response.error(apiResult(500, 'internal error (async)', %7Bdetails: err.stack%7D));%0A%09%09%09%09%7D%0A
 %09%09%09%7D);%0A%0A

add route check