 /**
 * Created by Gifer on 13.02.2017.
 */

 var Service    = require('./service.js');
 var console    = require('gifer-console');
 var URL        = require('url');
 var Uploader   = require('./mcUploading').upload;
 var _purl      = require('./mctools/other/purl').purl;
 var isAdminSid = require('./mcconnect').isAdminSid;
 var REST_API   = require('./mctools/mcREST');
 var CMD        = require('./cmd/cmd').CMD;
 var sendIntegrationAPI = require('./mctools/mcIntegrationAPI').sendApiCmdToServer;
 var fs         = require('fs');

 var countUpdatesDownloads = 0;
 var limitUpdatesDownloads = 0;

 function download (req, res, localPath, cacheHandler) {
     var file         = null;
     var path         = null;
     var downloadFile = null;
     var kanbanForum  = "";
     var rootPath     = "";

     try {
         file = URL.parse(req.url).pathname.split('.');
         path = Service.ExtractPath(req.url).split('/');

         kanbanForum = path[2] === "kanban" || path[2] === "forum" ? path[2] + "/" : "";
     } catch (e){ }

     if (file && path){
         if (path.length === 2 || (path.length === 3 && kanbanForum)){
             downloadFile = Service.ExtractFileName(req.url);
         } else {
             downloadFile = file.length > 1 ? path[path.length - 1] + "." + file[file.length - 1] : path[path.length - 1];
         }

         rootPath = MCPathes.Files + kanbanForum;

         if (MCServer.WEBUseCache && cacheHandler !== null) {
             cacheHandler(downloadFile, rootPath, req, res, function (next) {
                 if (next) {
                     Service.sendFiles(req, res, downloadFile, rootPath, function () {
                         setTimeout(function (){
                             var atime = new Date();

                             try {
                                 var stat = fs.statSync(rootPath + downloadFile);

                                 fs.utimesSync(rootPath + downloadFile, atime, stat.mtime);
                             } catch (e) {
                                 console.warn("cacheHandler, Change access time: " + rootPath + " - " + e.message);
                             }
                         }, 10);
                     });
                 }
             });
         } else {
             Service.sendFiles(req, res, downloadFile, rootPath, function () {
                 setTimeout(function () {
                     var atime = new Date();

                     try {
                         var stat = fs.statSync(rootPath + downloadFile);

                         fs.utimesSync(rootPath + downloadFile, atime, stat.mtime);
                     } catch (e) {
                         console.warn("Change access time: " + rootPath + " - " + e.message);
                     }
                 }, 10);
             });
         }
     } else {
         res.writeHead(404);
         res.end();
     }
 }

 function downloadUpdate(req, res, localPath, cacheHandler){
     limitUpdatesDownloads = require('./mctools/mcInternalConnection.js').getDownloadUpdatesLimit();

     if (limitUpdatesDownloads && countUpdatesDownloads + 1 > limitUpdatesDownloads) {
         res.statusCode = 509;

         res.end('Bandwidth Limit Exceeded');
     } else {
         var file = Service.ExtractFileName(req.url);

         countUpdatesDownloads++;

         if (MCServer.WEBUseCache && cacheHandler !== null){
             cacheHandler(URL.parse(req.url).pathname, MCPathes.Profile, req, res, function(next) {
                 if (next) {
                     Service.sendFiles(req, res, file, MCPathes.Updates, function (err, _uri, _rootPath) {
                         countUpdatesDownloads--;
                     });
                 }
             });
         } else {
             Service.sendFiles(req, res, file, MCPathes.Updates, function (err, _uri, _rootPath) {
                 countUpdatesDownloads--;
             });
         }

         console.log('[' + req.remoteHostIp + ', ' + (req.socket && req.socket._parent ? req.socket._parent.connectID : "") + ']: Downloading update file - ' + file);
     }
 }

 function downloadDB (req, res) {
     var filename = Service.ExtractFileName(req.url) || "";
     var downloadFile = filename.split('?')[0];
     var purl = _purl(req.url);
     var sid  = purl.param('sid');
     var uin  = purl.param('uin');
     var token= purl.param('token');
     var ip   = req.remoteHostIp;

     console.log('Try to download backupDB, ip: ' + ip);

     if (isAdminSid(sid, uin) && downloadFile){
         console.log('Download backupDB from web-admin, UIN: ' + uin);

         Service.sendFiles(req, res, downloadFile, MCPathes.Backup);
     } else

     if (token && downloadFile) {
         var hash = Service.RandomHash(10);

         require('./mctools/mcInternalConnection').sendDataFromInternalServer(
             CMD.ns_check_token + '=' + JSON.stringify({
                 ip     : ip,
                 remove : true,
                 token  : token,
                 where  : "backupdb",
                 hash   : hash
             }),

             function(info){
                 if (info.uin >= 0) {
                     console.log('Download backupDB, UIN: ' + info.uin);

                     Service.sendFiles(req, res, downloadFile, MCPathes.Backup);
                 } else {
                     console.err('Invalid token for UIN: ' + info.uin, console.logLevel.ERROR);

                     res.writeHead(404);
                     res.end();
                 }
             },
             hash
         );
     } else {
         console.err('Access denied for download backupDB, ip: ' + ip, console.logLevel.ERROR);

         res.writeHead(404);
         res.end();
     }
 }

 exports.aliasesIDX = {
     lobby : '2',
     admin : '6',
     chat  : '1',
     forum : '8',
     kanban: '7'
 };

 exports.list = function(aliases) {
     return {
         "1":  {
             pathWWW: '/' + aliases.chat.path + '/',
             realPath: '/chat/',
             enabled: aliases.chat.enabled,
             host: MCServer.Host,
             redirect: '/' + aliases.chat.path,
             runFunc: false,
             cache: true,
             source: MCPathes.WWW,
             type: CMD.ClientType.WEB_CHAT
         },
         "2":  {
             pathWWW: '/lobby/',
             host: MCServer.Host,
             runFunc: false,
             redirect: '/lobby',
             cache: true,
             source: MCPathes.WWW,
             type: CMD.ClientType.COMMON
         },
         "3":  {
             pathWWW: '/updates/',
             host: MCServer.Host,
             runFunc: true,
             noSSL: true,
             CallBack: function (req, res, localPath, cacheHandler) {
                 var hash = Service.RandomHash(7);

                 console.log("Router /updates/ check ip for download: " + req.remoteHostIp, console.logLevel.DEBUG);

                 require('./mctools/mcInternalConnection').sendDataFromInternalServer(CMD.ns_ip_filter + '=' + JSON.stringify({
                     hash: hash,
                     ip  : req.remoteHostIp,
                     type: CMD.ClientType.UPDATES
                 }), function(info){
                     if (info && info.access){
                         console.log("Router /updates/ ip: " + req.remoteHostIp + " is checked", console.logLevel.DEBUG);

                         downloadUpdate(req, res, localPath, cacheHandler);
                     } else {
                         res.statusCode = 403;
                         res.end(Service.Const.denied);

                         console.info("Router /updates/ blocked by IP filter for ip: " + req.remoteHostIp, console.logLevel.WARN);
                     }
                 }, hash);
             },
             type: CMD.ClientType.COMMON
         },
         "5":  {
             pathWWW: '/cmd/',
             host: MCServer.Host,
             cache: true,
             source: MCPathes.Service,
             type: CMD.ClientType.COMMON
         },
         "6":  {
             pathWWW: '/' + aliases.admin.path + '/',
             realPath: '/admin/',
             enabled: aliases.admin.enabled,
             host: MCServer.Host,
             redirect: '/' + aliases.admin.path,
             runFunc: false,
             cache: true,
             source: MCPathes.WWW,
             type: CMD.ClientType.WEB_ADMIN
         },
         "7":  {
             pathWWW: '/' + aliases.kanban.path + '/',
             realPath: '/kanban/',
             enabled: aliases.kanban.enabled,
             host: MCServer.Host,
             redirect: '/' + aliases.kanban.path,
             runFunc: false,
             cache: true,
             source: MCPathes.WWW,
             type: CMD.ClientType.WEB_KANBAN
         },
         "8":  {
             pathWWW: '/' + aliases.forum.path + '/',
             realPath: '/forum/',
             enabled: aliases.forum.enabled,
             host: MCServer.Host,
             redirect: '/' + aliases.forum.path,
             runFunc: false,
             cache: true,
             source: MCPathes.WWW,
             type: CMD.ClientType.WEB_FORUM
         },
         "9":  {
             pathWWW: '/wallpaper/',
             host: MCServer.Host,
             runFunc: false,
             cache: true,
             source: MCPathes.WWW,
             type: CMD.ClientType.COMMON
         },
         "11": {
             pathWWW: '/downloads/',
             host: MCServer.Host,
             runFunc: false,
             noSSL: true,
             source: function () {
                 return MCPathes.ProfilNode;
             },
             type: CMD.ClientType.COMMON
         },
         "12": {
             pathWWW: '/uploads/',
             host: MCServer.Host,
             runFunc: false,
             noSSL: true,
             source: function () {
                 return MCPathes.Profile;
             },
             type: CMD.ClientType.COMMON
         },
         "13": {
             pathWWW: '/uploading',
             host: MCServer.Host,
             hasParams: true,
             runFunc: true,
             noSSL: true,
             CallBack: Uploader,
             type: CMD.ClientType.COMMON
         },
         "14": {
             pathWWW: '/moment/',
             host: MCServer.Host,
             cache: true,
             source: MCPathes.NodeModules,
             type: CMD.ClientType.COMMON
         },
         "15": {
             pathWWW: '/admin/first.login',
             host: MCServer.Host,
             runFunc: true,
             CallBack: function (req, res) {
                 if (require('./mcconnect').firstLogin()) {
                     res.setHeader("Content-Type", "text/text");
                     res.end('OK');
                 } else {
                     res.writeHead(404);
                     res.end();
                 }
             },
             source: MCPathes.WWW,
             type: CMD.ClientType.WEB_ADMIN
         },
         "16": {
             pathWWW: '/textsource/',
             host: MCServer.Host,
             cache: true,
             source: MCPathes.Service,
             type: CMD.ClientType.COMMON
         },
         "17": {
             pathWWW: '/frameworks/',
             host: MCServer.Host,
             cache: true,
             source: MCPathes.Service,
             type: CMD.ClientType.COMMON
         },
         "18": {
             pathWWW: '/mctools/',
             host: MCServer.Host,
             cache: true,
             source: MCPathes.Service,
             type: CMD.ClientType.COMMON
         },
         /*
         "20" : {
             pathWWW  : '/vkCode',
             host     : MCServer.Host,
             runFunc  : true,
             CallBack : function(req, res){
                 var code = URL.parse(req.url).search;

                 VK.auth({
                     client_id     : '',
                     client_secret : "",
                     redirect_uri  : MCServer.Host + "/vkSuccess",
                     code          : code.split('=')[1]
                 }, function(err, response, data){
                     if (err){

                     } else {
                         console.log(data);
                     }

                     res.statusCode = 301;
                     res.setHeader('Location', '/');
                     res.end('');
                 });
             }
         },
        "22" : {
             pathWWW  : '/painter/',
             host     : MCServer.host,
             runFunc  : false,
             cache    : true,
             source	  : MCPathes.WWW
         },*/
         "23": {
             pathWWW: '/serverhelp/',
             host: MCServer.host,
             redirect: '/serverhelp',
             runFunc: false,
             cache: false,
             source: MCPathes.WWW
         },
         "24": {
             pathWWW: '/' + aliases.API.path + '/',
             realPath: '/API/',
             host: MCServer.host,
             runFunc: true,
             source: MCPathes.WWW,
             CallBack: sendIntegrationAPI,
             type: CMD.ClientType.INTEGRATION_API
         },
         "29": {
             pathWWW: '/' + aliases.files.path + '/',
             realPath: '/files/',
             host: MCServer.Host,
             noSSL: true,
             cache: false,
             runFunc: true,
             CallBack: download,
             type: CMD.ClientType.COMMON
         },
         "31": {
             pathWWW: '/' + aliases.support.path + '/',
             realPath: '/support/',
             host: MCServer.Host,
             redirect: '/' + aliases.support.path,
             runFunc: false,
             cache: true,
             source: MCPathes.WWW,
             type: CMD.ClientType.WEB_SUPPORT
         },
         "32": {
             pathWWW: '/' + aliases.support.path + '/',
             realPath: '/support/',
             host: MCServer.Host,
             redirect: '/' + aliases.support.path + '.html',
             cache: false,
             type: CMD.ClientType.WEB_SUPPORT
         },
         "33": {
             pathWWW: '/backupdb/',
             host: MCServer.Host,
             runFunc: true,
             cache: false,
             CallBack: downloadDB,
             type: CMD.ClientType.WEB_ADMIN
         },
         "34": {
             pathWWW: '/rest/',
             host: MCServer.Host,
             runFunc: true,
             cache: false,
             CallBack: REST_API,
             type: CMD.ClientType.COMMON
         },
         "35": {
             pathWWW: '/smileys/',
             host: MCServer.Host,
             cache: true,
             source: MCPathes.Service,
             type: CMD.ClientType.COMMON
         },
         "36": {
             pathWWW: '/setup/',
             CallBack: function (req, res) {
                 var filename = Service.ExtractFileName(req.url);

                 if (filename.indexOf('mcclient_') === 0) {
                     Service.sendFiles(req, res, 'mcsetup.exe', MCPathes.Setup);
                 } else {
                     res.writeHead(404);
                     res.end();
                 }
             },
             host: MCServer.Host,
             runFunc: true,
             cache: false,
             type: CMD.ClientType.COMMON
         },
         "37": {
             pathWWW: '/en/serverhelp',
             host: MCServer.host,
             runFunc: false,
             cache: false,
             redirectTo: '41' // lobby
         },
         "38": {
             pathWWW: '/getSupportOptions.js',
             host: MCServer.host,
             runFunc: true,
             cache: false,
             CallBack: function (req, res) {
                 var hash = Service.RandomHash(15);

                 require('./mctools/mcInternalConnection').sendDataFromInternalServer(
                     CMD.ns_support_options + "=" + JSON.stringify({hash: hash}),

                     function(info){
                         info.who = info.items;

                         res.end("window.__setMyChatOption(" + JSON.stringify(info) + ");");
                     },
                     hash
                 );
             },
             type: CMD.ClientType.WEB_SUPPORT
         },
         "39": {
             pathWWW: '/userdata/',
             host: MCServer.Host,
             runFunc: false,
             cache: true,
             source: function () {
                 return MCPathes.ProfilNode;
             }
         },
         "40": {
             pathWWW: '/.well-known/acme-challenge/',
             host   : MCServer.Host,
             runFunc: false,
             source : function () {
                 return MCPathes.LE;
             },
             type: CMD.ClientType.COMMON
         },
         "41": {
             pathWWW: '/serverhelp/en/',
             host: MCServer.host,
             realPath: '/serverhelp/en/',
             runFunc: false,
             cache: false,
             source: MCPathes.WWW
         },
         "42": {
             pathWWW: '/plugins/',
             host: MCServer.host,
             redirect: '/plugins',
             noSSL: true,
             runFunc: false,
             cache: true,
             source: MCPathes.Profile
         },
         "43": {
             pathWWW: '/qrcode/',
             host: MCServer.host,
             redirect: '/qrcode',
             runFunc: false,
             cache: false,
             source: MCPathes.WWW
         },
         "44": {
             pathWWW: '/serverhelp/ua/',
             host: MCServer.host,
             realPath: '/serverhelp/ua/',
             runFunc: false,
             cache: false,
             source: MCPathes.WWW
         },
         "45": {
             pathWWW: '/serverhelp/ru/',
             host: MCServer.host,
             realPath: '/serverhelp/ru/',
             runFunc: false,
             cache: false,
             source: MCPathes.WWW
         },

         "100": {
             pathWWW: '/',
             host: MCServer.Host,
             runFunc: false,
             cache: false,
             redirectTo: '2', // lobby
             type: CMD.ClientType.COMMON
         },
     };
 };